We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
接近相册翻页那样的体验的控件,手机里是非常常用的。但是一直没有用。 正好借这次项目实践的机会体验一把
按历史来说翻页控件应该是ViewPager。现在有了更时新的组件ViewPager2了。我们从最新版本开始学起,啥历史包袱都可以统统扔掉
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01" 在build.gradle中增加如下依赖
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
ViewPager2和RecyclerView之间不清不楚的关系 在使用过程中,发现ViewPager2和RecyclerView竟然有90%的相似度,直觉上感觉这不是一个巧合 通过源码可以发现他们之间采用了适配器模式,RecyclerView就藏在ViewPager2里面
Apapter ViewPager2的Apapter和RecyclerView是共用的都是RecyclerView.Adapter扩展的 其中针对ViewPager2有一个FragmentStateAdapter,顾名思义,内容都是以Fragment为子项。针对我的应用来说这个适配器“太重”了,所以我使用RecyclerView一样级别的数据项级别就好
BindingAdapter 为了配合MVVM模式,需要相关的BindingAdapter 由于ViewPager2和RecyclerView没有直接继承关系,所以还要仿造RecyclerView的BindingAdapter再写一遍(几乎是复制粘贴)
@BindingAdapter(value = {"itemsSource", "itemTemplate", "variableId"} ) public static <T> void setPager2Items(ViewPager2 viewPager2, List<T> itemsSource, @LayoutRes int itemTemplate, int variableId, CircleIndicator3 indicator) { ShadowAdapter<T> adapter; @SuppressWarnings("unchecked") ShadowAdapter<T> oldAdapter = (ShadowAdapter<T>) viewPager2.getAdapter(); if (oldAdapter == null) { ItemTemplate template = ItemTemplate.of(itemTemplate, variableId); adapter = new ShadowAdapter<>(template); } else { adapter = oldAdapter; } adapter.setItems(itemsSource); if (oldAdapter != adapter) { viewPager2.setAdapter(adapter); } }
<androidx.viewpager2.widget.ViewPager2 android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="12dp" app:itemsSource="@{dataContext.nearbySpaces}" app:itemTemplate="@{@layout/item_space}" app:variableId="@{dataContext.variableId}" android:layout_width="match_parent" android:layout_height="112dp" />
其中子项的view我直接用RecyclerView共用的了
运行报错啊!
space365.app E/space365: │ ----------UncaughtException throw--------- : java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.viewpager2.widget.ViewPager2$4.onChildViewAttachedToWindow(ViewPager2.java:277) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.recyclerview.widget.RecyclerView.dispatchChildAttached(RecyclerView.java:7872) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:893) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8902) 2022-03-21 15:41:18.640 3863-3863/com.space365.app E/space365: │ at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8860)
看来最外层的View的height必须是“match_parent”,这个和RecyclerView的“固定”高度略有不同 多想一下也能理解,只能再加一个item_space_page的layout
总算正常运行了,布局不用声明,默认就是横向的。 但是好像少了一些什么。 对没有“进度条”显示
这次我使用第三方控件方案
CircleIndicator 增加依赖implementation 'me.relex:circleindicator:2.1.6'
implementation 'me.relex:circleindicator:2.1.6'
BindingAdapter调整
@BindingAdapter(value = {"itemsSource", "itemTemplate", "variableId","indicator"} ,requireAll = false) public static <T> void setPager2Items(ViewPager2 viewPager2, List<T> itemsSource, @LayoutRes int itemTemplate, int variableId, CircleIndicator3 indicator) { ShadowAdapter<T> adapter; @SuppressWarnings("unchecked") ShadowAdapter<T> oldAdapter = (ShadowAdapter<T>) viewPager2.getAdapter(); if (oldAdapter == null) { ItemTemplate template = ItemTemplate.of(itemTemplate, variableId); adapter = new ShadowAdapter<>(template); } else { adapter = oldAdapter; } adapter.setItems(itemsSource); if (oldAdapter != adapter) { viewPager2.setAdapter(adapter); } if( indicator != null ){ indicator.setViewPager( viewPager2 ); //adapter.registerAdapterDataObserver(indicator.getAdapterDataObserver()); } }
把CircleIndicator3变量引入
<androidx.viewpager2.widget.ViewPager2 android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="12dp" app:itemsSource="@{dataContext.nearbySpaces}" app:itemTemplate="@{@layout/item_space_page}" app:variableId="@{dataContext.variableId}" app:indicator="@{spaceIndicator}" android:layout_width="match_parent" android:layout_height="112dp" /> <me.relex.circleindicator.CircleIndicator3 android:id="@+id/space_indicator" app:ci_drawable="@color/gray_400" app:ci_drawable_unselected="@color/gray_600" android:layout_width="match_parent" android:layout_height="20dp"/>
layout的声明,把CircleIndicator3作为绑定导入 OK
其他方案
也是一个好方案,但是好吧我承认我想偷懒
另外感谢 @marclee44 冠冠 相关的技术支持,其实这部分输入联合创作
The text was updated successfully, but these errors were encountered:
No branches or pull requests
安卓的翻页浏览控件
接近相册翻页那样的体验的控件,手机里是非常常用的。但是一直没有用。
正好借这次项目实践的机会体验一把
ViewPager2
按历史来说翻页控件应该是ViewPager。现在有了更时新的组件ViewPager2了。我们从最新版本开始学起,啥历史包袱都可以统统扔掉
Quick Start
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
在build.gradle中增加如下依赖
ViewPager2和RecyclerView之间不清不楚的关系
在使用过程中,发现ViewPager2和RecyclerView竟然有90%的相似度,直觉上感觉这不是一个巧合
通过源码可以发现他们之间采用了适配器模式,RecyclerView就藏在ViewPager2里面
Apapter
ViewPager2的Apapter和RecyclerView是共用的都是RecyclerView.Adapter扩展的
其中针对ViewPager2有一个FragmentStateAdapter,顾名思义,内容都是以Fragment为子项。针对我的应用来说这个适配器“太重”了,所以我使用RecyclerView一样级别的数据项级别就好
BindingAdapter
为了配合MVVM模式,需要相关的BindingAdapter
由于ViewPager2和RecyclerView没有直接继承关系,所以还要仿造RecyclerView的BindingAdapter再写一遍(几乎是复制粘贴)
其中子项的view我直接用RecyclerView共用的了
运行报错啊!
看来最外层的View的height必须是“match_parent”,这个和RecyclerView的“固定”高度略有不同
多想一下也能理解,只能再加一个item_space_page的layout
总算正常运行了,布局不用声明,默认就是横向的。
但是好像少了一些什么。
对没有“进度条”显示
进度UI实现
这次我使用第三方控件方案
CircleIndicator
增加依赖
implementation 'me.relex:circleindicator:2.1.6'
BindingAdapter调整
把CircleIndicator3变量引入
layout的声明,把CircleIndicator3作为绑定导入
OK
其他方案
也是一个好方案,但是好吧我承认我想偷懒
另外感谢 @marclee44 冠冠 相关的技术支持,其实这部分输入联合创作
官网其实讲的不是很详细,还需要另外查资料补充下
The text was updated successfully, but these errors were encountered: