web-dev-qa-db-fra.com

Scroll ne fonctionne pas pour plusieurs RecyclerView dans BottomSheet

J'ai implémenté BottomSheet en utilisant l'approche DialogFragment. J'ai TabLayout et ViewPager dans BottomSheet. La ViewPager héberge 2 pages, chacune gonfle une RecyclerView. Le premier (onglet Café) RecyclerView défile bien. Le problème que j'ai maintenant est que pour le deuxième (onglet Lait), le parchemin ne fonctionne pas. Une idée, comment puis-je résoudre ce problème? Merci!

Vous pouvez tester le projet de démonstration que j'ai créé ici: https://github.com/choongyouqi/bottomsheet `

 enter image description here

11
You Qi

Comme mentionné par R. Zagórski, j’ai décrit la raison de ce comportement de défilement ici , c’est-à-dire, BottomSheetBehavior ne prend en charge qu’un enfant défilant. Cependant, cette réponse ne portait pas sur les dialogues de fond.

Par conséquent - tout comme R. Zagórski - j'ai étendu ma propre bibliothèque qui surmonte cette limitation. À partir de 0.0.3, il existe un support pour les dialogues de feuille de fond! Vous pouvez trouver la bibliothèque et l'exemple d'application ici: https://github.com/laenger/ViewPagerBottomSheet

Pour l'utiliser dans votre projet, ajoutez simplement l'URL du dépôt maven à votre build.gradle:

repositories {
    maven { url "https://raw.github.com/laenger/maven-releases/master/releases" }
}

Ajoutez la bibliothèque aux dépendances:

dependencies {
    compile "biz.laenger.Android:vpbs:0.0.3"
}

Utilisez ViewPagerBottomSheetDialogFragment comme super classe pour les fragments de dialogue. Ensuite, configurez un ViewPager dans la vue de contenu:

public class DialogFragment extends ViewPagerBottomSheetDialogFragment {
    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        final View contentView = View.inflate(getContext(), R.layout.dialog_bottom_sheet, null);

        final ViewPager viewPager = (ViewPager) contentView.findViewById(R.id.viewpager);
        // ...
        BottomSheetUtils.setupViewPager(viewPager);

        dialog.setContentView(contentView);
    }
}

 sample implementation

7
laenger

En essayant de rechercher le problème sur StackOverflow, j'ai trouvé ce fil . Il décrit le bogue (du moins c'est ce que je vois), que BottomSheetBehaviour ne fonctionne que pour le premier enfant à défilement qu'il trouve. Il propose également l'utilisation de différents CoordinatorLayout.Behavior proposés et publiés ici .

Cependant, votre cas est un peu différent. BottomSheetDialogFragment est utilisé. Et c'est là que la solution fournie ne fonctionne pas. Cependant, j'ai réussi à surmonter ce problème. Published repository , où votre projet a été modifié pour fonctionner. Il utilise la variable ViewPagerBottomSheetBehavior de la bibliothèque mentionnée précédemment.

Fondamentalement, les modifications suivantes ont été apportées:

  1. StatisticFragment étend ViewPagerBottomSheetDialogFragment et non BottomSheetDialogFragment
  2. La fonction onCreateDialog dans StatisticsFragment est modifiée:

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        ViewPagerBottomSheetDialog dialog = (ViewPagerBottomSheetDialog) super.onCreateDialog(savedInstanceState);
        View rootView = View.inflate(getContext(), R.layout.sheet_main, null);
        viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
        tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
        dialog.setContentView(rootView);
        mBehavior = ViewPagerBottomSheetBehavior.from((View) rootView.getParent());
        mBehavior.setPeekHeight(400);
        if (viewPager != null && tabLayout != null) {
            initViewPager();
        }
        return dialog;
    }
    
  3. La fonction suivante est invoquée sur la ViewPager:

    BottomSheetUtils.setupViewPager(viewPager);
    

Et c'est tout. Le projet fonctionne.

Ce qui suit est fait dans les coulisses:

BottomSheetDialogFragment a une seule méthode: 

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new BottomSheetDialog(getContext(), getTheme());
}

BottomSheetDialog est retourné. Toutefois, le comportement défini de manière statique est défini sur BottomSheetBehavior. Ce qui était nécessaire, c’était d’annuler ViewPagerBottomSheetDialogFragment pour renvoyer ViewPagerBottomSheetDialogCoordinatorLayout.Behavior était défini sur ViewPagerBottomSheetBehavior. La coutume BottomSheet devait également être modifiée pour s’habituer à ViewPagerBottomSheetBehavior.

4
R. Zagórski

vous pouvez utiliser 2 RecyclerView dans CoordinatorLayout.

<Android.support.design.widget.CoordinatorLayout
         Android:id="@+id/mainBottomSheet"
         Android:layout_width="match_parent"
         Android:layout_height="match_parent"
         Android:background="@color/white">

         <Android.support.v7.widget.RecyclerView
                  Android:id="@+id/recyclerViewRight"
                  Android:layout_width="match_parent"
                  Android:layout_height="match_parent" />

         <Android.support.v7.widget.RecyclerView
                  Android:id="@+id/recyclerViewLeft"
                  Android:layout_width="200dp"
                  Android:layout_height="match_parent" />

</Android.support.design.widget.CoordinatorLayout>

vérifier ce post link

1
Rasoul Miri

Vous n'avez pas besoin d'étendre StatisticFragment en tant que ViewPagerBottomSheetDialogFragment ou de ne pas avoir besoin d'utiliser une bibliothèque pour cela.

C'est votre code que je viens d'apporter quelques modifications dans votre Static Fragment par rapport à View Pager.

Voici le Statistic Fragment dans lequel j'ai apporté des modifications. 

Il n'y a pas de bugs comme indiqué dans toutes les réponses ci-dessus.

Remplacez ce code par votre ancien Static fragment. Aucune autre modification ne vous donnera la sortie souhaitée.

Je viens d’apporter des modifications avec votre View Pager uniquement et de le faire fonctionner à votre guise. Used OnPageChangeListener method vient d’obtenir cette vue.

Fragment statistique.Java

    public class StatisticFragment extends BottomSheetDialogFragment {

        private BottomSheetBehavior mBehavior;
        private TabLayout tabLayout;
        private ViewPager viewPager;

        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
            View rootView = View.inflate(getContext(), R.layout.sheet_main, null);

            viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
            tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
            if (viewPager != null && tabLayout != null) {
                initViewPager();
            }

            final ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {

                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                }

                @Override
                public void onPageSelected(int arg0) {
                    // TODO Auto-generated method stub
                    View view = viewPager.findViewWithTag(arg0);
                    if (view == null) {
                        return;
                    }
                    CustomPagerAdapter adapter = new CustomPagerAdapter(getContext());
                    viewPager.setAdapter(adapter);
                    viewPager.setOffscreenPageLimit(10);
                    tabLayout.setupWithViewPager(viewPager);
                }

                @Override
                public void onPageScrollStateChanged(int state) {

                }
            };

            viewPager.addOnPageChangeListener(pageChangeListener);
            viewPager.post(new Runnable() {
                @Override
                public void run() {
                    pageChangeListener.onPageSelected(viewPager.getCurrentItem());
                }
            });


            dialog.setContentView(rootView);
            mBehavior = BottomSheetBehavior.from((View) rootView.getParent());
            return dialog;


        }

        private void initViewPager() {
            CustomPagerAdapter adapter = new CustomPagerAdapter(getContext());
            viewPager.setAdapter(adapter);
            viewPager.setOffscreenPageLimit(10);
            tabLayout.setupWithViewPager(viewPager);

        }

        @Override
        public void onStart() {
            super.onStart();
            //mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            //mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        }

        public class ServiceVideHolder extends RecyclerView.ViewHolder {
            protected ViewGroup mItemView;
            protected TextView mNameView;
            protected TextView mCodeView;

            public ServiceVideHolder(View v) {
                super(v);
                //rootView = v;
                mItemView = (ViewGroup) v.findViewById(R.id.item);
                mNameView = (TextView) v.findViewById(R.id.main_text);
                mCodeView = (TextView) v.findViewById(R.id.sub_text);
            }
        }

        public class ItemViewHolder extends RecyclerView.ViewHolder {
            protected TextView mMainText;
            protected TextView mSubText;

            public ItemViewHolder(View v) {
                super(v);
                mMainText = (TextView) v.findViewById(R.id.main_text);
                mSubText = (TextView) v.findViewById(R.id.sub_text);
            }
        }

        public class ItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {
            private List<Item> items;

            public ItemAdapter(List<Item> items) {
                this.items = items;
            }

            @Override
            public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
                return new ItemViewHolder(view);
            }

            @Override
            public void onBindViewHolder(final ItemViewHolder viewHolder, final int position) {
                final Item item = items.get(position);
                viewHolder.mMainText.setText(item.name);
                viewHolder.mSubText.setText(item.value);
                viewHolder.mMainText.setTextColor(ResourcesCompat.getColor(getResources(), position % 2 == 0 ? R.color.md_red_500 : R.color.md_blue_500, null));
            }

            @Override
            public int getItemCount() {
                return items.size();
            }
        }

        class ViewPagerAdapter extends FragmentPagerAdapter {
            private final List<Fragment> mFragmentList = new ArrayList<>();
            private final List<String> mFragmentTitleList = new ArrayList<>();

            public ViewPagerAdapter(FragmentManager manager) {
                super(manager);
            }

            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }

            @Override
            public int getCount() {
                return mFragmentList.size();
            }

            public void addFrag(Fragment fragment, String title) {
                mFragmentList.add(fragment);
                mFragmentTitleList.add(title);
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return mFragmentTitleList.get(position);
            }
        }

        public class CustomPagerAdapter extends PagerAdapter {

            private Context mContext;

            public CustomPagerAdapter(Context context) {
                mContext = context;
            }

            @Override
            public Object instantiateItem(ViewGroup collection, int position) {
                //CustomPagerEnum customPagerEnum = CustomPagerEnum.values()[position];
                LayoutInflater inflater = LayoutInflater.from(mContext);
                ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.adapter, collection, false);
                rootView.setTag(position);


                Toast.makeText(mContext, "Inside Instanciate Item", Toast.LENGTH_SHORT).show();

                //View rootView = View.inflate(getContext(), R.layout.adapter, null);
                final RecyclerView mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
                ArrayList<Item> items = new ArrayList<>();

                if (position == 0) {
                    items.add(new Item("Coffee 1", "1"));
                    items.add(new Item("Coffee 2", "2"));
                    items.add(new Item("Coffee 3", "3"));
                    items.add(new Item("Coffee 4", "4"));
                    items.add(new Item("Coffee 5", "5"));
                    items.add(new Item("Coffee 6", "6"));
                    items.add(new Item("Coffee 7", "7"));
                    items.add(new Item("Coffee 8", "8"));
                    items.add(new Item("Coffee 9", "9"));
                    items.add(new Item("Coffee 10", "10"));
                } else {
                    items.add(new Item("Milk 1", "1"));
                    items.add(new Item("Milk 2", "2"));
                    items.add(new Item("Milk 3", "3"));
                    items.add(new Item("Milk 4", "4"));
                    items.add(new Item("Milk 5", "5"));
                    items.add(new Item("Milk 6", "6"));
                    items.add(new Item("Milk 7", "7"));
                    items.add(new Item("Milk 8", "8"));
                    items.add(new Item("Milk 9", "9"));
                    items.add(new Item("Milk 10", "10"));
                }

                final ItemAdapter mAdapter = new ItemAdapter(items);

                mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
                mRecyclerView.setNestedScrollingEnabled(false);
                mRecyclerView.setAdapter(mAdapter);
                Paint paint = new Paint();
                Paint.setStrokeWidth(1);
                Paint.setColor(ResourcesCompat.getColor(getResources(), R.color.md_grey_500, null));
                Paint.setAntiAlias(true);
                Paint.setPathEffect(new DashPathEffect(new float[]{25.0f, 25.0f}, 0));
                mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).showLastDivider().Paint(paint).build()); //.marginResId(R.dimen.leftmargin, R.dimen.rightmargin)

                collection.addView(rootView);


                return rootView;
            }

            @Override
            public void destroyItem(ViewGroup collection, int position, Object view)    {
                collection.removeView((View) view);
            }

            @Override
            public int getCount() {
                return 2;
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public CharSequence getPageTitle(int position) {
                //CustomPagerEnum customPagerEnum = CustomPagerEnum.values()[position];
                return position == 0 ? "Coffee" : "Milk";
            }

        }
    }

C'est fait.

 enter image description here

0
Jay Rathod RJ