Die Verknüpfung zwischen Androids RecycleView und ViewPager und Fragment

Unter normalen Umständen verwenden wir beim Schreiben von Seitenverknüpfungen Tablayout zum Verknüpfen mit ViewPager und Fragment. Aufgrund des Stils von TabLayout gibt es jedoch einige Fälle, die unsere UI-Anforderungen nicht erfüllen können. Daher versuchen wir, RecycleView zum Verknüpfen von ViewPager und Fragmentz zu verwenden , und dann gute Ergebnisse erzielt. Als nächstes werde ich es mit Ihnen teilen.
Das erste ist die Layoutdatei:

       <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/cl_food"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:background="@color/grey29"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/cl_discount">

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/rv_type"
                        android:layout_width="0dp"
                        android:layout_height="@dimen/dp128"
                        android:layout_marginLeft="@dimen/dp21"
                        android:layout_marginTop="@dimen/dp_w_31"
                        android:layout_marginRight="@dimen/dp21"
                        android:visibility="visible"
                        app:layout_constraintLeft_toLeftOf="parent"
                        app:layout_constraintRight_toRightOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                    <com.ikonke.hotel.ui.weight.WrapContentHeightViewPager
                        android:id="@+id/vp_food"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="@dimen/dp21"
                        android:layout_marginTop="@dimen/dp29"
                        android:layout_marginRight="@dimen/dp21"
                        android:layout_marginBottom="@dimen/dp29"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintLeft_toLeftOf="parent"
                        app:layout_constraintRight_toRightOf="parent"
                        app:layout_constraintTop_toBottomOf="@+id/rv_type" />

                </androidx.constraintlayout.widget.ConstraintLayout>

Da es sich bei unserem Fragment um eine Liste handelt, tritt bei Verwendung des nativen ViewPagers zur Angabe der adaptiven Höhe das Phänomen auf, dass der untere Teil der Liste nicht im Einschränkungslayout gezeichnet werden kann. Daher wird hier der ViewPager mit einer benutzerdefinierten adaptiven Höhe verwendet

public class WrapContentHeightViewPager extends ViewPager {

    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

    public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int height = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height) height = h;
        }
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Wenn Sie einen benutzerdefinierten ViewPager verwenden, können Sie im Einschränkungslayout eine adaptive Höhe angeben, und es gibt keine Ausnahmen. Nachdem die Layoutdateien geschrieben wurden, ist der nächste Schritt die Verknüpfung. Zuerst müssen wir einen Adapter für ViewPager schreiben
.

public class FoodViewPagerAdapter extends FragmentPagerAdapter {
    ArrayList<Fragment> mlist;

    public FoodViewPagerAdapter(@NonNull FragmentManager fm, ArrayList<Fragment> list) {
        super(fm);
        this.mlist = list;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return mlist.get(position);//显示第几个页面
    }

    @Override
    public int getCount() {
        return mlist.size();//有几个页面
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return null;
    }

}

Dann stellen Sie den Adapter ein

  FoodViewPagerAdapter foodViewPagerAdapter = new FoodViewPagerAdapter(getFragmentManager(), fragList);
  vpFood.setAdapter(foodViewPagerAdapter);

Hier werden nur zwei Parameter übergeben. Der zweite Parameter ist die Anzahl der Fragmente. Die Anzahl der Fragmente sollte der Anzahl der Titel entsprechen. Unsere Titel sind angefordert und dürfen nicht festgelegt werden, daher habe ich sie in einer Schleife zur Sammlung von Fragmenten hinzugefügt . Wenn Sie über eine feste Anzahl von Fragmenten verfügen, können Sie hier auch eine Festcodierung vornehmen

Dann müssen wir der Titelliste (anstelle der Tablayout-Liste) ein Elementklickereignis zuweisen, und dann muss der übergebene Wert den Index des Elements haben und dann die ViewPager-Methode zum Schieben und Wechseln verwenden

    mTopAdapter.setOnItemClickListener((position, bean) -> {
            //定义一个值让标题列表选中条目的下标跟ViewPager选中页面的下标进行共享,并实时更新
            mPosition = position;
            //切换ViewPager页面
            vpFood.setCurrentItem(position, true);
            menuId = bean.getRecipeId();
            //切换选中条目
            for (RecipeInfoBean bean1 : foodTypeList) {
                bean1.setSel(false);
            }
            bean.setSel(true);
            mTypeAdapter.notifyDataSetChanged();
            mTopAdapter.notifyDataSetChanged();
        });

Die Methode zum Umschalten von ViewPager übergibt zwei Parameter: Der erste Parameter dient dazu, ViewPager zu der Seite zu wechseln, deren Index mit dem Index des ausgewählten Elements in der Titelliste übereinstimmt, und der zweite Parameter steuert, ob verschoben werden soll oder nicht.

Jetzt wird der Effekt des Seitenwechsels durch Verknüpfen von ViewPager mit der Titelliste realisiert. Als Nächstes muss die ViewPager-Seite verschoben werden, um den Auswahleffekt der Elemente in der Titelliste zu ändern

        vpFood.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
				//判断共享下标跟当前页面下标是否一致,不一致的话就把共享下标更新并且切换标题列表的条目选中效果
                if (mPosition != position) {
                    mPosition = position;
                    //设置所有条目都为不选中
                    for (RecipeInfoBean bean1 : foodTypeList) {
                        bean1.setSel(false);
                    }
                    //设置当前下标的条目为选中
                    foodTypeList.get(position).setSel(true);
                    //刷新适配器展示效果
                    mTypeAdapter.notifyDataSetChanged();
                    mTopAdapter.notifyDataSetChanged();
                }
                //请求数据
                mPresenter.getFoods(foodTypeList.get(position).getRecipeId(), foodTypeList.get(position).getId());
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

Dann legen Sie am besten die folgenden Eigenschaften für die Liste in unserem Fragment fest: Der Layout-Manager sollte auf nicht verschiebbar eingestellt sein

mGridLayoutManager.setScrollEnabled(false);

Ich entferne dieses Attribut und es gibt keine Anomalie, aber es ist am besten, es hinzuzufügen, um Unfälle zu vermeiden. Seitdem ist
die Verknüpfung beendet. Da wir schließlich die MVP-Architektur verwenden, werden die Daten dann im ausgewählten Monitor des ViewPagers angefordert in der V-Schicht. Rufen Sie in der Methode zum Anzeigen des Anforderungsergebnisses die Set-Methode im Fragment auf, um die in RecycleView im Fragment anzuzeigenden Daten zu aktualisieren. Wenn Sie MVC verwenden, können Sie direkt im ausgewählten Monitor des ViewPagers eine Anfrage stellen. Geben Sie dann das Anforderungsergebnis weiter. Das Obige ist die Zusammenfassung des Autors. Ich
hoffe, ich kann Ihnen, den Lesern, helfen. Wenn der Artikel Fehler enthält, weisen Sie ihn bitte rechtzeitig darauf hin, um die Leser nicht in die Irre zu führen. Vielen Dank

Guess you like

Origin blog.csdn.net/m0_46366678/article/details/125673947