侧滑菜单在列表布局中越来越常见,其良好的交互为 App 增色了不好,在 Android 中,其实现方式也有很多种,本文是基于自定义 ViewGroup 方式实现,使用时在列表 item 布局中引入该 Layout 即可。
实现效果图:
所用知识点:
- 自定义 ViewGroup
- ScrollTo() 和 ScrollTo() 区别及用法
- getScrollX(),getScrollY() 表示的意义及用法
- Scroller用法
- Android 事件分发机制
1. ScrollTo() 和 ScrollBy() 区别及用法
scrollTo() : 滑动到指定坐标位置点,是绝对滑动。
scrollBy() : 相对于当前位置滑动一段距离,是相对滑动,其内部实现是基于 scrollTo() 实现的,在当前位置坐标点加上滑动距离。
注意:滑动的是 View 的内容,并不是滑动 View 本身。
2. getScrollX() 和 getScrollY() 表示意义和用法
图上面,褐色的框,其实就是我们眼睛看到的手机界面,就是一个窗口。
而绿色的长方体呢,就是一块可以左右拉动的幕布啦,其实也就是我们要显示在窗口上面的内容,它其实是可以很大的,大到无限大,只是没在窗口中间的,所以我们就看不到。
而getScrollX 其实获取的值,就是这块 幕布在窗口左边界时候的值了,而幕布上面哪个点是原点(0,0)呢?就是初始化时内容显示的位置。
所以当我们将幕布往右推动的时候,幕布在窗口左边界的值就会在0的左边(-100),而向左推动,则其值会是在0的右边(100)。
举例:
效果:
3.Scroller 用法
(1).原理介绍:
scrollTo() 和 scrollBy() 实现的是一个结果,即是说,当调用scrollTo(100,0) 时,再重新绘制时,内容已经出现在(100,0)位置上,缺少一个移动的过程,而 Scroller 就是帮助我们实现这个滚动的过程的。
动画的原理其实不停的重绘位置变化的内容,在视觉效果上,就产生了动画的效果。
(2) 使用步骤:
- 创建 Scroller 对象,一般是在 构造方法中创建。
private Scroller mScroller;
public SwipeMenuLayout(Context context) {
this(context, null);
}
public SwipeMenuLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeMenuLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScroller = new Scroller(context);
}
- 重写 自定义 View 的 computeScroll() 方法。下面代码基本不会变化。
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) { // 动画没有结束
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
- 调用 Scroller 的 startScroll()方法,并 invalidate() 重绘 View.
mScroller.startScroll(int startX,int startY,int dx,int dy); // startX起始坐标,dx 偏移量
invalidate();
4.自定义 ViewGroup - SwipeMenuLayout
- 自定义属性 attrs.xml
<resources>
<declare-styleable name="SwipeMenuLayout">
<attr name="leftMenuId" format="reference" />
<attr name="rightMenuId" format="reference" />
<attr name="contentId" format="reference" />
</declare-styleable>
</resources>
SwipeMenuLayout.java
public class SwipeMenuLayout extends ViewGroup {
private static final String TAG = "SwipeMenuLayout";
private Scroller mScroller;
private int mScaledTouchSlop;
private int leftMenuId;
private int rightMenuId;
private Vi