Android - добавьте фрагмент с настраиваемыми параметрами

В настоящее время я добавляю фрагмент, используя следующий код.

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();
}

Следующий код предназначен для изменения размера добавленного фрагмента.

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;
}

Но вместо добавления и затем изменения размера, как добавить фрагмент с настраиваемыми размерами (высота, ширина и поля)?

Ответ 1

Вы можете передать желаемую ширину и маржу ширины для фрагмента и присвоить это значение при раздувании представления

Например, если вы используете фрейм-макет как контейнер для фрагментов, тогда передайте значения с помощью метода нового экземпляра

/**
         * 
         * @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;
        }

И затем примените их в методе onCreateView. Обратите внимание, если вы используете фрейм-макет как контейнер для фрагментов, тогда используйте FrameLayout param else, который вы получите исключение.

   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);  

Результат: -

Оранжевый фон - это мой контейнер Frame layout, а все остальные изменены Fragments с настраиваемыми полями в одном контейнере. Вы также можете поиграть с свойством LayoutParam.Gravity, чтобы они двигались влево, вправо, вправо, в центр, снизу-центр, верхний центр и т.д.

введите описание изображения здесь

Полный код, который я использовал в примере

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;
            }
        }
    }

Итак, технически это выполнимо, но я не понял, почему вы пытаетесь сделать это?

Ответ 2

Вы можете сделать это, указав LayoutParams в фрагменте onCreateView, например:

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;
}

Ответ 3

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();

Ответ 4

Почему бы не попробовать создать свою собственную ViewGroup? Обязанностью ViewGroup является настройка положения детей в onLayout() и его размерах в onMeasure(). Просто добавьте необходимые методы просмотра и переопределения с логикой и ограничениями, которые вы хотите.

Ответ 5

Вы можете установить размеры в представлении контейнера, R.id.fragment_container в вашем случае, и пусть фрагмент займет все свободное пространство.