2016-06-29 10 views
12

Obecnie dodałem fragment używając następującego kodu.Android - dodaj fragment o niestandardowych wymiarach

private void addFragment(Fragment fragment, String fragmentName) { 
    Log.i("Adder", "Adding fragment " + fragmentName); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.add(R.id.fragment_container, fragment, fragmentName); 
    fragmentTransaction.commit(); 
} 

Poniższy kod służy do zmiany rozmiaru dodanego fragmentu.

private boolean readjustFragment(Fragment fragmentToBeAdjusted, FragmentCoordinates fragmentCoordinates) { 
    if (fragmentToBeAdjusted != null) { 
     View view = fragmentToBeAdjusted.getView(); 
     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(fragmentCoordinates.getWidth(), fragmentCoordinates.getHeight()); 
     params.leftMargin = fragmentCoordinates.getX0(); 
     params.bottomMargin = fragmentCoordinates.getY0(); 
     view.setLayoutParams(params); 
     view.requestLayout(); 
     return true; 
    } 
    return false; 
} 

Jak dodać fragment z niestandardowymi wymiarami (wysokość, szerokość i marginesy) zamiast dodawać, a następnie zmieniać rozmiar?

Odpowiedz

6

Można przekazać żądaną szerokość wysokość i margines do fragmentu i przypisać tę wartość podczas pompowania pogląd

Na przykład, jeśli używasz układ ramowy jako pojemnik na fragmenty następnie przekazywać wartości z nowej metody instancji

/** 
     * 
     * @param widthInDP 
     * @param heightinDP 
     * @param leftMarginDp 
     * @param topMarginDp 
     * @param rightMarginDp 
     * @param bottomMarginDp 
     * @param fragIndex 
     * @return 
     */ 
     public static PlaceholderFragment newInstance(int widthInDP, 
       int heightinDP, int leftMarginDp, int topMarginDp, 
       int rightMarginDp, int bottomMarginDp, int fragIndex) { 
      PlaceholderFragment resizableFragment = new PlaceholderFragment(); 

      Bundle args = new Bundle(); 

      // Test purpose Only 
      args.putInt(INDEX, fragIndex); 

      // Set Width Height dynamically 
      args.putInt(WIDTH, widthInDP); 
      args.putInt(HEIGHT, heightinDP); 

      // SetMargin 
      args.putInt(LEFT_MARGIN, leftMarginDp); 
      args.putInt(RIGHT_MARGIN, rightMarginDp); 
      args.putInt(TOP_MARGIN, topMarginDp); 
      args.putInt(BOTTOM_MARGIN, bottomMarginDp); 
      resizableFragment.setArguments(args); 

      return resizableFragment; 
     } 

A następnie zastosować je w metodzie onCreateView. Zwróć uwagę, że jeśli używasz układu ramek jako pojemnika na fragmenty, użyj parametru FrameLayout param inaczej otrzymasz wyjątek.

FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) rootView 
      .getLayoutParams(); 

    // set width height 
    params.height = dpToPx(getArguments().getInt(HEIGHT)); 
    params.width = dpToPx(getArguments().getInt(WIDTH)); 

    // substitute 
    // parameters for left,top, right, bottom 
    params.setMargins(dpToPx(getArguments().getInt(LEFT_MARGIN)), 
      dpToPx(getArguments().getInt(TOP_MARGIN)), 
      dpToPx(getArguments().getInt(RIGHT_MARGIN)), 
      dpToPx(getArguments().getInt(BOTTOM_MARGIN))); 
    rootView.setLayoutParams(params); 

wyjściowa: -

Pomarańczowe tło jest moja Frame layout pojemnik i wszystkie inne są przeskalowane Fragments z niestandardowymi marż w tym samym pojemniku. Można też poeksperymentować z LayoutParam.Gravity nieruchomości, aby je przejść w lewo prawo, góra, dół, środek, centrum oddolne, górną, środkową i tak dalej

enter image description here

Kompletny kod użyłem w próbce

package com.example.fragment; 

    import android.annotation.TargetApi; 
    import android.graphics.Color; 
    import android.os.Build; 
    import android.os.Bundle; 
    import android.support.v4.app.Fragment; 
    import android.support.v4.app.FragmentActivity; 
    import android.util.DisplayMetrics; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.FrameLayout; 
    import android.widget.TextView; 

    public class MainActivity extends FragmentActivity { 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      if (savedInstanceState == null) { 
       getSupportFragmentManager() 
         .beginTransaction() 
         .add(R.id.container, 
           PlaceholderFragment.newInstance(400, 400, 50, 50, 
             50, 50, 1)).commit(); 

       getSupportFragmentManager() 
         .beginTransaction() 
         .add(R.id.container, 
           PlaceholderFragment.newInstance(300, 300, 30, 30, 
             30, 30, 2)).commit(); 

       getSupportFragmentManager() 
         .beginTransaction() 
         .add(R.id.container, 
           PlaceholderFragment.newInstance(200, 200, 20, 20, 
             20, 20, 3)).commit(); 

       getSupportFragmentManager() 
         .beginTransaction() 
         .add(R.id.container, 
           PlaceholderFragment.newInstance(100, 100, 10, 10, 
             10, 10, 4)).commit(); 
      } 
     } 

     /** 
     * A placeholder fragment containing a simple view. 
     */ 
     @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
     public static class PlaceholderFragment extends Fragment { 

      private static final String HEIGHT = "Height"; 
      private static final String WIDTH = "Width"; 
      private static final String LEFT_MARGIN = "left"; 
      private static final String RIGHT_MARGIN = "right"; 
      private static final String TOP_MARGIN = "top"; 
      private static final String BOTTOM_MARGIN = "bottom"; 

      // Test Data 
      private static final String INDEX = "FragNumber"; 

      /** 
      * 
      * @param widthInDP 
      * @param heightinDP 
      * @param leftMarginDp 
      * @param topMarginDp 
      * @param rightMarginDp 
      * @param bottomMarginDp 
      * @param fragIndex 
      * @return 
      */ 
      public static PlaceholderFragment newInstance(int widthInDP, 
        int heightinDP, int leftMarginDp, int topMarginDp, 
        int rightMarginDp, int bottomMarginDp, int fragIndex) { 
       PlaceholderFragment resizableFragment = new PlaceholderFragment(); 

       Bundle args = new Bundle(); 

       // Test purpose Only 
       args.putInt(INDEX, fragIndex); 

       // Set Width Height dynamically 
       args.putInt(WIDTH, widthInDP); 
       args.putInt(HEIGHT, heightinDP); 

       // SetMargin 
       args.putInt(LEFT_MARGIN, leftMarginDp); 
       args.putInt(RIGHT_MARGIN, rightMarginDp); 
       args.putInt(TOP_MARGIN, topMarginDp); 
       args.putInt(BOTTOM_MARGIN, bottomMarginDp); 
       resizableFragment.setArguments(args); 

       return resizableFragment; 
      } 

      public PlaceholderFragment() { 
      } 

      public int dpToPx(int dp) { 
       DisplayMetrics displayMetrics = getActivity().getResources() 
         .getDisplayMetrics(); 
       int px = Math.round(dp 
         * (displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT)); 
       return px; 
      } 

      @Override 
      public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) { 

       View rootView = inflater.inflate(R.layout.fragment_main, container, 
         false); 

       FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) rootView 
         .getLayoutParams(); 

       // set width height 
       params.height = dpToPx(getArguments().getInt(HEIGHT)); 
       params.width = dpToPx(getArguments().getInt(WIDTH)); 

       // substitute 
       // parameters for left,top, right, bottom 
       params.setMargins(dpToPx(getArguments().getInt(LEFT_MARGIN)), 
         dpToPx(getArguments().getInt(TOP_MARGIN)), 
         dpToPx(getArguments().getInt(RIGHT_MARGIN)), 
         dpToPx(getArguments().getInt(BOTTOM_MARGIN))); 
       rootView.setLayoutParams(params); 

       // Test purpose Only 
       switch (getArguments().getInt(INDEX)) { 
       case 1: 
        rootView.setBackgroundColor(Color.MAGENTA); 

        ((TextView) rootView.findViewById(R.id.frag_index)) 
          .setText("Fragment # " + getArguments().getInt(INDEX)); 

        break; 

       case 2: 
        rootView.setBackgroundColor(Color.GREEN); 

        ((TextView) rootView.findViewById(R.id.frag_index)) 
          .setText("Fragment # " + getArguments().getInt(INDEX)); 

        break; 

       case 3: 
        rootView.setBackgroundColor(Color.BLUE); 

        ((TextView) rootView.findViewById(R.id.frag_index)) 
          .setText("Fragment # " + getArguments().getInt(INDEX)); 

        break; 

       default: 
        rootView.setBackgroundColor(Color.WHITE); 

        ((TextView) rootView.findViewById(R.id.frag_index)) 
          .setText("Fragment # " + getArguments().getInt(INDEX)); 

        break; 
       } 

       return rootView; 
      } 
     } 
    } 

Technicznie jest to możliwe, ale nie rozumiem, dlaczego próbujesz to zrobić w ten sposób?

+2

Właśnie wydrukowałem to rozwiązanie =) Nie zapominaj, że LayoutParams powinien mieć typ twojego kontenera. – Alexander

+0

Zgaduję, że wskazuję właściwy kierunek. –

+0

Tak, to dobre rozwiązanie. Ale użyłem buildera zamiast newInstance. – Alexander

-1

Możesz ustawić wymiary w widoku kontenera, R.id.fragment_container w twoim przypadku, i pozwolić fragmentowi zająć całą dostępną przestrzeń.

+0

Potrzebuję pojemnika, aby móc zawierać wiele fragmentów. Kiedy zmiana rozmiaru fragmentu jest możliwa, dlaczego nie mogę ustawić rozmiaru podczas samego dodawania? – jay

2

Można to zrobić poprzez określenie LayoutParams w fragment za onCreateView, tak -

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.so_demo_frag,container,false); 
    RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 400); 
    v.setLayoutParams(p); 
    return v; 
} 
1

Dlaczego nie spróbować tworzyć własne ViewGroup? Obowiązkiem ViewGroup jest dostosowanie pozycji dziecka w onLayout() i jego rozmiarów w onMeasure(). Po prostu rozbuduj potrzebną grupę przeglądową i nadpisz metody z logiką i ograniczeniami, których potrzebujesz.

2
Just add it with framelayout in your mainActvity and add your fragment like this: 

     <FrameLayout 
      android:id="@+id/playfragment" 
      android:layout_width="match_parent" 
      android:layout_height="30dp" /> 


FragmentPlay frg2 = new FragmentPlay();//create the fragment instance for the top fragment 
     FragmentManager manager = getSupportFragmentManager();//create an instance of fragment manager 
     FragmentTransaction transaction = manager.beginTransaction();//create an instance of Fragment-transaction 
     transaction.add(R.id.playfragment, frg2, "Frag_Top_tag"); 
     transaction.commit(); 
+0

Zrobiłem dokładnie to samo, dodając nowy fragment, ale potrzebowałem sposobu, aby dynamicznie ustawić wymiary fragmentu. Rozwiązanie Hitesha było naprawdę fajnym sposobem na osiągnięcie tego. – jay