描述
这周做了一个自定义侧滑布局, 继承自LinearLayout。
代码地址:android-SwipeLinearLayout
效果
可以单独使用,也可以在ListView等可滑动的父组件中使用。以在ListView中使用为demo:
解决了item和ListView的滑动冲突, 同时每个item及其上面的控件可以正常点击。
代码比较简单,就不上传到JCenter了。 控件本身就只有一个文件: SwipeLinearLayout.java, 有需要可以直接复制或者修改。
使用
和普通LinearLayout一样使用,内部包含2个子元素即可。
示例:
<xx.SwipeLinearLayout
xxxx>
<LinearLayout
android:layout-width="match_parent"
xxxx
xxxx>
... ...
</LinearLayout>
<LinearLayout
android:layout-width="30dp"
xxxx>
... ...
</LinearLayout>
</xx.SwipeLinearLayout>
第一个子元素是未侧滑时就显示的部分, 第二个子元素是会被侧滑出来的部分。
SwipeLinearLayout的orientation随便设置,反正都会当成horizontal处理。
public SwipeLinearLayout(Context context) {
this(context, null);
}
public SwipeLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScroller = new Scroller(context);
this.setOrientation(HORIZONTAL);
}
实现
如何进行滑动
这个问题思路很简单。滑动分为2个阶段, 一个阶段就是跟手滑动,另外一个阶段,就是当手指离开后,布局继续滑动。
跟手滑动,那么我们很容易就想到重写onTouchEvent方法,在ACTION_MOVE事件中实现。那手指离开之后呢?首先要明确一点,开始处理的判断,是放在ACTION_UP事件中的。我们可以通过此时布局展开的程度,决定布局是要完全展开,还是缩回初始状态。为了让这种自动的滚动显得自然,我们需要借助Scroller。
Scroller可以看作一种类似插值器一样的东西,可以在系统调用的回调中,为我们提供一个起、终值之间的值。随着时间的增长,这个值逐渐从起点值变成终点值。通过这个值随时间的变化,可以帮助我们实现布局的平滑滚动。
处理滑动的代码如下:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
lastX = event.getX();
lastY = event.getY();
startScrollX = getScrollX();