带吸附效果的ViewPager(一)
2016-05-05 13:52
381 查看
什么叫吸附效果?先看一个示例更为直观,借用网上的一个效果图:
类似这种效果的app很多,网上的实现方法也是很多,但各种重写各种监听又令人不胜其烦,今日突发奇想,顺着自己的思路实现了类似的效果,不敢独享,特来分享给大家!
做事要一步一步来,不能一口吃胖,知道原理,接下来的事情就好办了!所以第一篇,暂且实现一个简单的效果,如图:
实现思路(原理):
1.ScrollView
外层ScrollView不必说了!
2.滑动监听
我们要实现这种效果,那么ScrollView的滑动监听必不可少,当scrollview上滑动至图中的snapbar顶部位置时以及下滑出snapbar顶部位置时对该吸附控件的操作!网上大多数是通过重写View来实现的,本人则取巧通过事先在顶部位置布局的控件以显示隐藏来实现的,当scrollview上滑动至snapbar顶部位置显示控件,下滑至该位置时再隐藏,是不是很简单?但需注意一点是,我们需要计算snapbar以上部分布局的高度,才能在scrollview滑动监听中判断是否滑动到了这一位置:
本人将这部分的高度固定为160dp,只需将160dp转换为px就可以了,另外我们在类似这样的布局时也尽量能固定顶部这一部分的高度,方便计算,如果使用的是wrap_parent怎需动态计算高度,相对麻烦!
3.吸附控件布局
布局时,是需要两个相同的snapbar布局的,一个是跟随scrollview滑动的,一个是固定在顶部且初始状态为隐藏的。如何操作即第二步的操作方法!
因为6.0以前的SDK,ScrolView是无法直接使用onScrollChanged来监听滑动距离的,因此我们需要稍稍重写下ScrollView并自定义一个接口来将onScrollChanged事件暴露出来:
snapbar上部高度计算:
滑动监听:
就此简单几步就可以实现了,哈哈!
MainActivity:
activity_main.xml(为了方便起见,列表数据是直接放在了布局文件中的):
类似这种效果的app很多,网上的实现方法也是很多,但各种重写各种监听又令人不胜其烦,今日突发奇想,顺着自己的思路实现了类似的效果,不敢独享,特来分享给大家!
做事要一步一步来,不能一口吃胖,知道原理,接下来的事情就好办了!所以第一篇,暂且实现一个简单的效果,如图:
实现思路(原理):
1.ScrollView
外层ScrollView不必说了!
2.滑动监听
我们要实现这种效果,那么ScrollView的滑动监听必不可少,当scrollview上滑动至图中的snapbar顶部位置时以及下滑出snapbar顶部位置时对该吸附控件的操作!网上大多数是通过重写View来实现的,本人则取巧通过事先在顶部位置布局的控件以显示隐藏来实现的,当scrollview上滑动至snapbar顶部位置显示控件,下滑至该位置时再隐藏,是不是很简单?但需注意一点是,我们需要计算snapbar以上部分布局的高度,才能在scrollview滑动监听中判断是否滑动到了这一位置:
本人将这部分的高度固定为160dp,只需将160dp转换为px就可以了,另外我们在类似这样的布局时也尽量能固定顶部这一部分的高度,方便计算,如果使用的是wrap_parent怎需动态计算高度,相对麻烦!
3.吸附控件布局
布局时,是需要两个相同的snapbar布局的,一个是跟随scrollview滑动的,一个是固定在顶部且初始状态为隐藏的。如何操作即第二步的操作方法!
因为6.0以前的SDK,ScrolView是无法直接使用onScrollChanged来监听滑动距离的,因此我们需要稍稍重写下ScrollView并自定义一个接口来将onScrollChanged事件暴露出来:
package com.byl.snappingviewpager; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; /** * Created by baiyuliang on 2016-5-5. */ public class MyScrollView extends ScrollView { private ScrollViewListener scrollViewListener = null; public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } public interface ScrollViewListener { void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy); } }
snapbar上部高度计算:
snapbar_y = dip2px(this, 160);//注意你的snapbar以上部分的高度值,将其转换为px(最好设置为固定值,如果非固定,则要动态计算高度)
/** * 将dp转px * * @param context * @param dpValue * @return */ public int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }
滑动监听:
scrollView.setScrollViewListener(new MyScrollView.ScrollViewListener() { @Override public void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy) { if (y >= snapbar_y) { rg_snapbar_top.setVisibility(View.VISIBLE); } else { rg_snapbar_top.setVisibility(View.GONE); } } });
就此简单几步就可以实现了,哈哈!
MainActivity:
package com.byl.snappingviewpager; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { MyScrollView scrollView; TextView tv_snapbar_top,tv_snapbar; int snapbar_y; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); snapbar_y=dip2px(this,160);//注意你的snapbar以上部分的高度值,将其转换为px(最好设置为固定值,如果非固定,则要动态计算高度) } private void initView() { scrollView= (MyScrollView) findViewById(R.id.scrollView); tv_snapbar_top= (TextView) findViewById(R.id.tv_snapbar_top); tv_snapbar= (TextView) findViewById(R.id.tv_snapbar); scrollView.setScrollViewListener(new MyScrollView.ScrollViewListener() { @Override public void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy) { if(y>=snapbar_y){ tv_snapbar_top.setVisibility(View.VISIBLE); }else{ tv_snapbar_top.setVisibility(View.GONE); } } }); tv_snapbar_top.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "snapbar_top", Toast.LENGTH_SHORT).show(); } }); tv_snapbar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "snapbar", Toast.LENGTH_SHORT).show(); } }); } /** * 将dp转px * @param context * @param dpValue * @return */ public int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }
activity_main.xml(为了方便起见,列表数据是直接放在了布局文件中的):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#EEEEEE" tools:context="com.byl.snappingviewpager.MainActivity"> <com.byl.snappingviewpager.MyScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" android:scrollbars="none"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="160dp" android:background="@color/colorPrimaryDark"> <ImageView android:id="@+id/iv_headView" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerInParent="true" android:src="@mipmap/ic_launcher" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/iv_headView" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:text="白玉梁" android:textColor="#FFFFFF" /> </RelativeLayout> <TextView android:id="@+id/tv_snapbar" android:layout_width="match_parent" android:layout_height="40dp" android:background="#FF6600" android:gravity="center_vertical" android:paddingLeft="5dp" android:textColor="#FFFFFF" android:text="snapbar" /> <!-- 以下为列表内容,为了方便,直接写在了布局中 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题1" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题2" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题3" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题4" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题5" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题6" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题7" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题8" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题9" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="1dp" android:background="#FFFFFF" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题10" android:textColor="#333333" android:textSize="16sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容" android:textColor="#666666" /> </LinearLayout> </LinearLayout> </com.byl.snappingviewpager.MyScrollView> <TextView android:id="@+id/tv_snapbar_top" android:layout_width="match_parent" android:layout_height="40dp" android:background="#FF6600" android:textColor="#FFFFFF" android:gravity="center_vertical" android:paddingLeft="5dp" android:text="snapbar" android:visibility="gone" /> </RelativeLayout>
相关文章推荐
- 简述文件上传原理之 jsp - servlet 篇
- MyEclipse优化设置(最详细版本)
- 带吸附效果的ViewPager(一)
- Binder机制
- SVN命令大全
- win7搭建maven环境
- android 实现SQLite开启事务
- 转载:《.NET 编程结构》专题汇总(C#)
- Js/Jquery获取iframe中的元素
- google一些搜索技巧
- socket中read、write、send、recv函数的比较
- tomcat配置单向认证
- Android Orm框架分析
- remote tracking branches
- 【VS开发】PCIe体系结构的组成部件
- 【HUSTOJ】1041: 阿姆斯特朗数
- POJ 3050-Hopscotch(BFS)
- PerfMon Metrics Collector插件的Disks I/O使用总结
- iOS之修改项目BUG之旅--(二)
- ipvsadm 命令参考