web-dev-qa-db-ja.com

BottomSheetの複数のRecyclerViewでスクロールが機能しない

BottomSheetアプローチを使用してDialogFragmentを実装しました。 TabLayoutViewPagerBottomSheetがあります。 ViewPagerは2ページをホストしており、それぞれがRecyclerViewを膨らませています。最初の([コーヒー]タブ)RecyclerViewは正常にスクロールします。私が今持っている問題は、2番目(ミルクタブ)ではスクロールが機能しないことです。どうすればこれを修正できますか?ありがとう!

ここで作成したデモプロジェクトでテストできます: https://github.com/choongyouqi/bottomsheet `

enter image description here

15
You Qi

R.Zagórskiが述べたように、このスクロール動作の理由を説明しました here 、つまり、BottomSheetBehaviorは1つのスクロール子のみをサポートします。ただし、この回答はボトムシートダイアログに焦点を当てていませんでした。

したがって、R。ザゴルスキーと同様に、この制限を克服する独自の library を拡張しました。 0.0.3以降、ボトムシートダイアログがサポートされます!ライブラリとサンプルアプリはこちらからご覧いただけます: https://github.com/laenger/ViewPagerBottomSheet

プロジェクトで使用するには、mavenリポジトリのURLをbuild.gradleに追加するだけです。

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

ライブラリを依存関係に追加します。

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

ViewPagerBottomSheetDialogFragmentをダイアログフラグメントのスーパークラスとして使用します。次に、コンテンツビュー内にViewPagerを設定します。

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

StackOverflowで問題を検索しようとしたところ、 this thread が見つかりました。それは、バグについて(少なくとも私がそれを見る方法です)、BottomSheetBehaviourは最初に見つかったスクロール可能な子に対してのみ機能することを示しています。また、提案され公開されているさまざまなCoordinatorLayout.Behaviorhere の使用法も提案しています。

ただし、ケースは少し異なります。 BottomSheetDialogFragmentが使用されます。そして、これは提供されたソリューションが機能しない場所です。しかし、なんとかこの問題を克服することができました。公開 リポジトリ 、プロジェクトが機能するように変更された場所。前述のライブラリのViewPagerBottomSheetBehaviorを使用します。

基本的に、次の変更が行われました。

  1. StatisticFragmentViewPagerBottomSheetDialogFragmentではなくBottomSheetDialogFragmentを拡張します
  2. StatisticsFragmentのonCreateDialog関数が変更されました:

    @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. 次の関数がViewPagerで呼び出されます:

    BottomSheetUtils.setupViewPager(viewPager);
    

そして、それがすべてです。プロジェクトは機能します。

以下は裏で行われます:

BottomSheetDialogFragmentには1つのメソッドしかありません:

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

そこでBottomSheetDialogが返されます。ただし、静的に定義された動作はBottomSheetBehaviorに設定されています。 ViewPagerBottomSheetDialogFragmentをオーバーライドしてViewPagerBottomSheetDialogを返すことで、CoordinatorLayout.BehaviorViewPagerBottomSheetBehaviorに設定されました。また、BottomSheetに慣れるには、カスタムViewPagerBottomSheetBehaviorをオーバーライドする必要がありました。

4
R. Zagórski

coordinatorLayoutで2 RecyclerViewを使用できます。

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

この投稿をチェック リンク

0
Rasoul Miri

StatisticFragmentViewPagerBottomSheetDialogFragmentとして拡張する必要はなく、そのためにライブラリを使用する必要もありません。

Static Fragmentに関連するView Pager.に変更を加えたばかりのコードです

これが私が変更を加えたStatistic Fragmentです。

上記のすべての回答に記載されているようなバグはありません。

このコードを古いStatic fragmentで置き換えてください。望ましい出力が得られる他の変更はありません。

View Pagerのみを変更し、ご希望どおりに機能させることができました。 OnPageChangeListenerメソッドを使用すると、そのビューを取得できます。

Statistic Fragment.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";
            }

        }
    }

完了です

enter image description here

0
Jay Rathod RJ