滑动效果的View
2016-04-25 17:12
435 查看
像汽车之家找车界面点击后出现出现一个侧边栏,侧边栏可以根据手势滑动而滑动。
那我们就要自定义可以滑动的RelativeLayout, 当我们要使用 此功能的时候,需要将该Activity的顶层布局设置为SildingFinishLayout,然后需要调用setTouchView()方法来设置需要滑动的View现在就上代码说话:
自定义SildingFinishLayout .java
public class SildingFinishLayout extends RelativeLayout implements OnTouchListener { /** * SildingFinishLayout布局的父布局 */ private ViewGroup mParentView; /** * 处理滑动逻辑的View */ private View touchView; /** * 滑动的最小距离 */ private int mTouchSlop; /** * 按下点的X坐标 */ private int downX; /** * 按下点的Y坐标 */ private int downY; /** * 临时存储X坐标 */ private int tempX; /** * 滑动类 */ private Scroller mScroller; /** * SildingFinishLayout的宽度 */ private int viewWidth; /** * 记录是否正在滑动 */ private boolean isSilding; private OnSildingFinishListener onSildingFinishListener; private boolean isFinish; public SildingFinishLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SildingFinishLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mScroller = new Scroller(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { // 获取SildingFinishLayout所在布局的父布局 mParentView = (ViewGroup) this.getParent(); viewWidth = this.getWidth(); } } /** * 设置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity * * @param onSildingFinishListener */ public void setOnSildingFinishListener( OnSildingFinishListener onSildingFinishListener) { this.onSildingFinishListener = onSildingFinishListener; } /** * 设置Touch的View * * @param touchView */ public void setTouchView(View touchView) { this.touchView = touchView; touchView.setOnTouchListener(this); } public View getTouchView() { return touchView; } /** * 滚动出界面 */ private void scrollRight() { final int delta = (viewWidth + mParentView.getScrollX()); // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item mScroller.startScroll(mParentView.getScrollX(), 0, -delta + 1, 0, Math.abs(delta)); postInvalidate(); } /** * 滚动到起始位置 */ private void scrollOrigin() { int delta = mParentView.getScrollX(); mScroller.startScroll(mParentView.getScrollX(), 0, -delta, 0, Math.abs(delta)); postInvalidate(); } /** * touch的View是否是AbsListView, 例如ListView, GridView等其子类 * * @return */ private boolean isTouchOnAbsListView() { return touchView instanceof AbsListView; } /** * touch的View是否是StickyListHeadersListView * * @return */ private boolean isTouchOnStickyListHeadersListView() { return touchView instanceof StickyListHeadersListView; } /** * touch的view是否是ScrollView或者其子类 * * @return */ private boolean isTouchOnScrollView() { return touchView instanceof ScrollView; } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = tempX = (int) event.getRawX(); downY = (int) event.getRawY(); break; case MotionEvent.ACTION_MOVE: int moveX = (int) event.getRawX(); int deltaX = tempX - moveX; tempX = moveX; if (Math.abs(moveX - downX) > mTouchSlop && Math.abs((int) event.getRawY() - downY) < mTouchSlop) { isSilding = true; // 若touchView是AbsListView, // 则当手指滑动,取消item的点击事件,不然我们滑动也伴随着item点击事件的发生 if (isTouchOnAbsListView() ||isTouchOnStickyListHeadersListView() ) { MotionEvent cancelEvent = MotionEvent.obtain(event); cancelEvent .setAction(MotionEvent.ACTION_CANCEL | (event.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT)); v.onTouchEvent(cancelEvent); } } if (moveX - downX >= 0 && isSilding) { mParentView.scrollBy(deltaX, 0); // 屏蔽在滑动过程中ListView ScrollView等自己的滑动事件 if (isTouchOnScrollView() || isTouchOnAbsListView() || isTouchOnStickyListHeadersListView()) { return true; } } break; case MotionEvent.ACTION_UP: isSilding = false; if (mParentView.getScrollX() <= -viewWidth / 2) { isFinish = true; scrollRight(); } else { scrollOrigin(); isFinish = false; } break; } // 假如touch的view是AbsListView或者ScrollView 我们处理完上面自己的逻辑之后 // 再交给AbsListView, ScrollView自己处理其自己的逻辑 if (isTouchOnScrollView() || isTouchOnAbsListView() || isTouchOnStickyListHeadersListView()) { return v.onTouchEvent(event); } // 其他的情况直接返回true return true; } @Override public void computeScroll() { // 调用startScroll的时候scroller.computeScrollOffset()返回true, if (mScroller.computeScrollOffset()) { mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); if (mScroller.isFinished()) { if (onSildingFinishListener != null && isFinish) { onSildingFinishListener.onSildingFinish(); } else { //如果没有设置回调接口, 直接划到起始位置 // scrollOrigin(); } } } } public interface OnSildingFinishListener { public void onSildingFinish(); } }
xml运用:
<com.jeff.view.SildingFinishLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/sildingFinishLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/second_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/view_line" android:scrollbars="vertical" /> </com.jeff.view.SildingFinishLayout>
在Activity中直接调用setTouchView():
...... ListView listView = (ListView) view.findViewById(R.id.listView); SildingFinishLayout mSildingFinishLayout = (SildingFinishLayout) view.findViewById(R.id.sildingFinishLayout); mSildingFinishLayout.setOnSildingFinishListener(new SildingFinishLayout.OnSildingFinishListener() { @Override public void onSildingFinish() { getActivity().finish(); } }); mSildingFinishLayout.setTouchView(listView); .....
感谢大家的支持
相关文章推荐
- javascript 实现继承的几种方式
- 坑爹的oracle11g新特性 密码延迟验证
- ToString()的浅显解释(转)
- 为自己的本地站点封装域名
- 用数组实现线性表
- viewWillDisappear,viewWillAppear不调用的解决方法
- 可执行jar包
- TransMac 下载 win7 win10 U盘启动的制作方法 win7 win10 U盘启动的 transMac制作方法
- hdu 5661 异或
- 连八进制都不知道
- 【剑指offer-Java版】03二维数组中的查找
- ThreadLocal in java
- ruby 除法运算
- jQuery网页右侧固定层显示隐藏在线qq客服代码
- JavaScript基础学习(一)—JavaScript简介
- iOS开发——点击图片全屏显示
- android httpClient(https/http)的优化构建方式二
- oracle imp-000008错误的解决办法
- linux下Bash函数功能之编写脚本(十一)
- 利用Nunit进行单元测试 NHibernate在SQL server中建表