安卓手把手教你实现RecycleView横向和ViewPage的级联滑动
2016-06-02 20:52
573 查看
之前做过一个horizontalScrollView+viewpage的级联滑动,总结如下:
既然我们有了recycleView为何不用?
recycleview可以在horizontalScrollView的基础上增加多行,实现更多变更多定制化的效果。
我们都知道recycleview有三种效果:
inearLayoutManager 线形管理器,支持横向、纵向。
GridLayoutManager 网格布局管理器
StaggeredGridLayoutManager 瀑布流式布局管理器
(还不会recycleview基本使用的自行补粮:
http://blog.csdn.net/lmj623565791/article/details/45059587),
首先看一下我们要做什么事情:
监听recycleview的item点击事件
监听Viewpage的变化
recycleview实现横向的gridview
根据屏幕的宽度固定每个item的宽度
滑动viewpage,recycleview跟着滑动到对应item
点击recycleview的对应item,Viewpage跟着滑动到对应页
开始之前我们看一下效果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201606/d7e552452d7e9cc8d63b1b2ad32cb315)
看一下activity的布局:
这儿用到了百分比布局,花2分钟看我上一篇文章就秒懂。
(http://blog.csdn.net/u012534831/article/details/51511240)
看一下oncreate的代码
viewPager.setCurrentItem(position/4, true); 改变viewpage显示页面。
计算偏移量这儿我用了一个小的投机取巧的方式( mRecyclerView.smoothScrollToPosition(arg0*4+3),我没有使用计算得出的偏移量来设置滚动,而是根据这个方法的特性显示出下一列的最后一个数字(本应该是第一个),这样下一列就完全显示出来从而达到可操控的滚动
注:特性是指scrolltoposition这个方法会把你想要移动的item放到你能看见的地方,但是它不会管放到哪个位置,能让你看见就行,一般在末尾。
:下面我举例子解释一下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201606/d7945463e0621a053ed8b869f79a8c9f)
比如我滑到了第六页,准备显示第六行,也即为数字为20的item,因为ScrollToPosition这个方法只会把20显示出来,但是不管位置,所以它显示出来的效果是这样的:20跑到了19的下面,本应该是在17的右边的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201606/a2bc312549db0912ea575f337664bb36)
OK,那么我的方法就是把23显示到目前20的位置,这样20就被顶到17的位置了,在视觉上就实现了列的左平移。
第二:smoothScrollToPosition是从ScrollToPosition方法切换过来的,(如果不采用smoothScrollToPosition这个方法的话)不平滑滚动的话会出现两个问题:
一是视图无法滚动到最左边,二是当手动去滚动至最左边的时候item的位置出现错乱(虽然会自动恢复,但是有明显的视觉延迟)见下图样式:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201606/b12d9c036c3551198eae0d64011080e4)
可以看见,视图乱了,但是松手的话它会自动恢复。
数据就是36个数字
OK,我们再看一下recycleview的Adapter中bindviewholder的代码:
Constant.displayWidth*0.2即为屏幕宽度的1/5,依据屏幕宽度每行5个item。
现在我们梳理一下文章都有哪些内容:
第一:从布局中我们看出有一个viewpage和一个瀑布流的recycleview。
第二:设置为可滚动的recycleview。并限定每行5个item。
第三:在viewpage的onPageSelected方法里面计算recycleview的滑动距离。
第四:在recycleview的item点击事件里面设置viewpage的切换。
基本和我们前面确定的内容一致,写到这儿只是让大家了解一下基本思路就行了,知道联动该怎么去实现,对应什么方法,欢迎多多交流。下面给出源码(eclipse版本的):
csdn下载地址:http://download.csdn.net/detail/u012534831/9539449
git地址:https://github.com/qht1003077897/recycleview-viewpage—-Scroll.git
QQ:1003077897
github:https://github.com/qht1003077897
既然我们有了recycleView为何不用?
recycleview可以在horizontalScrollView的基础上增加多行,实现更多变更多定制化的效果。
我们都知道recycleview有三种效果:
inearLayoutManager 线形管理器,支持横向、纵向。
GridLayoutManager 网格布局管理器
StaggeredGridLayoutManager 瀑布流式布局管理器
(还不会recycleview基本使用的自行补粮:
http://blog.csdn.net/lmj623565791/article/details/45059587),
首先看一下我们要做什么事情:
监听recycleview的item点击事件
监听Viewpage的变化
recycleview实现横向的gridview
根据屏幕的宽度固定每个item的宽度
滑动viewpage,recycleview跟着滑动到对应item
点击recycleview的对应item,Viewpage跟着滑动到对应页
开始之前我们看一下效果:
看一下activity的布局:
<com.example.recycleviewtest.PercentLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="200dp"/> <com.example.recycleviewtest.PercentLinearLayout android:id="@+id/linearLayout" android:layout_width="500dp" android:layout_height="200dp" app:layout_heightPercent="30%h" app:layout_widthPercent="100%w"> <android.support.v7.widget.RecyclerView android:id="@+id/id_recyclerview" android:divider="#ffff0000" android:layout_width="match_parent" android:layout_height="match_parent"/> </com.example.recycleviewtest.PercentLinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" android:onClick="imageclick"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" android:tint="#ffcdd2"/> </LinearLayout> </com.example.recycleviewtest.PercentLinearLayout>
这儿用到了百分比布局,花2分钟看我上一篇文章就秒懂。
(http://blog.csdn.net/u012534831/article/details/51511240)
看一下oncreate的代码
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(ImageView)findViewById(R.id.imageview); viewPager = (ViewPager) findViewById(R.id.viewPager); initData(); mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview); // 采用瀑布流并设置4行水平滚动 StaggeredGridLayoutManager mStaggeredLayoutManager= new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL); mRecyclerView.setLayoutManager(mStaggeredLayoutManager); mRecyclerView.setAdapter(mAdapter = new HomeAdapter(MainActivity.this,mDatas)); mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));//每一列添加分割线 getDispaly(mRecyclerView);//获取屏幕尺寸,目的是为了等分屏幕宽度 mmAdapter = new MyPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mmAdapter); viewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { mRecyclerView.smoothScrollToPosition(arg0*4+3); } /** 此方法在滑动ViewPager的时候一直被调用,页面在滑动过程中不停触发该方法:position”按照api的解释是“目前显示在屏幕上的第一个页面,只要positionOffset不为0,那么他后面的页面同样是可见的 第一页~第二页 position = 0 positionOffset 0.0 ~ 1.0 第二页~第一页 position = 0 positionOffset 1.0 ~ 0.0 通过上面的结果,由于position的值在切换第一页和第二页的时候没有变化,就可以同过position+1得到右边的view,通过position拿到左边的view 不论是滑动还是静止,他表示的都是屏幕左边的页 positionOffset 移量的百分比 positionOffsetPixels 偏移量的数值*/ @Override public void onPageScrolled(int position, float offest, int offestPixes) { } /**当页面的滑动状态改变时该方法会被触发,页面的滑动状态有3个:0表示什么都不做,1表示开始滑动,2表示结束滑动*/ @Override public void onPageScrollStateChanged(int arg0) { } }); mAdapter.setOnItemClickerListener(new OnItemClickerListener() { @Override public void OnItemClicker(View view, int position) { // TODO Auto-generated method stub //只能去点击第一行的item,即4的倍数 if(position%4==0){ viewPager.setCurrentItem(position/4, true); //item从0-31,对应着viewpage的0-7页,所以说一列item对应一页 Toast.makeText(MainActivity.this, "你点击了"+position, Toast.LENGTH_SHORT).show(); } else{return;} } }); }
viewPager.setCurrentItem(position/4, true); 改变viewpage显示页面。
计算偏移量这儿我用了一个小的投机取巧的方式( mRecyclerView.smoothScrollToPosition(arg0*4+3),我没有使用计算得出的偏移量来设置滚动,而是根据这个方法的特性显示出下一列的最后一个数字(本应该是第一个),这样下一列就完全显示出来从而达到可操控的滚动
注:特性是指scrolltoposition这个方法会把你想要移动的item放到你能看见的地方,但是它不会管放到哪个位置,能让你看见就行,一般在末尾。
:下面我举例子解释一下:
比如我滑到了第六页,准备显示第六行,也即为数字为20的item,因为ScrollToPosition这个方法只会把20显示出来,但是不管位置,所以它显示出来的效果是这样的:20跑到了19的下面,本应该是在17的右边的。
OK,那么我的方法就是把23显示到目前20的位置,这样20就被顶到17的位置了,在视觉上就实现了列的左平移。
第二:smoothScrollToPosition是从ScrollToPosition方法切换过来的,(如果不采用smoothScrollToPosition这个方法的话)不平滑滚动的话会出现两个问题:
一是视图无法滚动到最左边,二是当手动去滚动至最左边的时候item的位置出现错乱(虽然会自动恢复,但是有明显的视觉延迟)见下图样式:
可以看见,视图乱了,但是松手的话它会自动恢复。
数据就是36个数字
protected void initData() { mDatas = new ArrayList<String>(); for (int i = 0; i < 36; i++) { mDatas.add("" + i); } }
OK,我们再看一下recycleview的Adapter中bindviewholder的代码:
public void onBindViewHolder(final MyViewHolder holder, int position) { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( (int)(Constant.displayWidth*0.2), (int)(Constant.recycleviewHeight*0.25)); holder.itemView.setLayoutParams(params); holder.tv.setText(mDatas.get(position)); if(onItemClickerListener!=null){ //提供给activity的点击回调 holder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub int p=holder.getLayoutPosition(); onItemClickerListener.OnItemClicker(holder.itemView, p); } }); } }
Constant.displayWidth*0.2即为屏幕宽度的1/5,依据屏幕宽度每行5个item。
现在我们梳理一下文章都有哪些内容:
第一:从布局中我们看出有一个viewpage和一个瀑布流的recycleview。
第二:设置为可滚动的recycleview。并限定每行5个item。
第三:在viewpage的onPageSelected方法里面计算recycleview的滑动距离。
第四:在recycleview的item点击事件里面设置viewpage的切换。
基本和我们前面确定的内容一致,写到这儿只是让大家了解一下基本思路就行了,知道联动该怎么去实现,对应什么方法,欢迎多多交流。下面给出源码(eclipse版本的):
csdn下载地址:http://download.csdn.net/detail/u012534831/9539449
git地址:https://github.com/qht1003077897/recycleview-viewpage—-Scroll.git
QQ:1003077897
github:https://github.com/qht1003077897
相关文章推荐
- flume1.6 centos6.x 安装与配置
- 示例1.6 文件拷贝
- Android Camera HAL3中预览preview模式下的控制流
- 解决重新安装sqlserver2008报错Reporting Services目录数据库文件存在的问题
- 示例1.5 字符流输出
- 解决重新安装sqlserver2008报错Reporting Services目录数据库文件存在的问题
- 集群资源管理与调度概要
- 第二阶段团队项目冲刺站立会议(十)
- iOS的REST服务-备
- 套接字—Socket
- http://www.cnblogs.com/technology/p/4467895.html
- Web 服务器错误代码
- 示例1.4 字节流输出
- 夜间模式 values-night
- shell脚本的时间指令date
- ipv6 自从6月1号开始Appstore的审核需要支持ipv6
- linux配置SSH协议免登录密码
- error:could not open ...jvm.cfg解决方法
- 即时通信
- 示例1.3 文件过滤器