背景
一般上下滑动的全屏界面,都是使用viewpager做。
好处是系统封装好了,可以直接调用相应的api就能使用
坏处是viewpager的刷新机制比较麻烦,而且往头部添加数据也不是很方便
后来有人使用RecyclerView+PagerSnapHelper将recyclerview打造成类似viewpage的效果
好处是recyclerview功能强大,能满足大部分需求
坏处是这俩个搭配会有很多小bug需要你慢慢优化
viewpager2
这篇文章主要讲的就是viewpage2
google官网上更新的viewpager2
首先看下本文实现的效果
首先来看下viewpage2的基本用法
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-27'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
首先引入本文需要的第三方库
viewpager使用的是androidx版本
项目怎么转为androidx这篇文章就不讲了
直接上xml开始
mainactivity
viewpage2 = findViewById(R.id.page2);
smartRefreshLayout = findViewById(R.id.refresh);
smartRefreshLayout.setEnableLoadMore(true);
adapter = new Adapter();
viewpage2.setAdapter(adapter);
for (int i = 0; i < 3; i++) {
list.add(i + "");
}
adapter.setList(list);
adapter的内容为
class Adapter extends RecyclerView.Adapter {
List list = new ArrayList<>();
public void setList(List list) {
this.list = list;
notifyDataSetChanged();
}
public void addHead(String s) {
list.add(0, s);
notifyDataSetChanged();
}
void addFoot(String s) {
list.add(s);
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bindData(list.get(position) + "");
}
@Override
public int getItemCount() {
return list.size();
}
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.num);
}
void bindData(String s) {
textView.setText(s);
}
}
可以看到viewpage2的adapter 是继承recycerview的adapter,
其实viewpage2内部也还是通过recyclerview+PagerSnapHelper实现的
打开viewpage2的源码可以看到
LinearLayoutManager mLayoutManager;
private int mPendingCurrentItem = NO_POSITION;
private Parcelable mPendingAdapterState;
private RecyclerView mRecyclerView;
private PagerSnapHelper mPagerSnapHelper;
private ScrollEventAdapter mScrollEventAdapter;
private CompositeOnPageChangeCallback mPageChangeEventDispatcher;
private FakeDrag mFakeDragger;
private PageTransformerAdapter mPageTransformerAdapter;
private boolean mUserInputEnabled = true;
所以viewapge2是支持横向和竖版的滑动的
接下来我们给viewpage2添加刷新头
这里使用的是smartrefresh
github地址为https://github.com/scwang90/SmartRefreshLayout
接下里修改mainactivity的代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpage2 = findViewById(R.id.page2);
smartRefreshLayout = findViewById(R.id.refresh);
smartRefreshLayout.setEnableLoadMore(true);
adapter = new Adapter();
viewpage2.setAdapter(adapter);
for (int i = 0; i < 3; i++) {
list.add(i + "");
}
adapter.setList(list);
viewpage2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
if (position == list.size() - 1) {
Toast.makeText(getApplicationContext(), position + "触发loadmore", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
}
下拉刷新通过smartrefresh的监听来做
smartrefresh的用法可以参考github
加载更多的方式可以通过smartrefresh的监听来做也可以通过viewpage2. registerOnPageChangeCallback在滑动到最后一个的时候触发loadmore
这样就实现了一个简单的类似抖音的主界面框架
本文代码https://github.com/BigSweet/ViewPage2Demo