Android--ListView的item水平滑动效果

本文介绍了如何在Android中实现ListView的item水平滑动效果,包括自定义Item布局和ListView,详细讲解了自定义布局的设置、滑动事件处理及ListView的OnTouchEvent方法。通过这种方式,可以在滑动时展示额外的视图,如QQ聊天界面的删除按钮功能。
摘要由CSDN通过智能技术生成

ListView的item水平滑动效果

---------------------------------------------------------------------

步骤:

1、自定义Item布局view
1、自定义布局中有至少两个view要显示:一个正常显示的布局contentView,一个隐藏起来的布局menuView
2、自定义布局中,设置两个布局的位置,通过onMeasure(),onLayout()两个方法设置
3、定义一个滑动处理方法,从父类获取到滑动事件,对滑动效果处理。
ACTION_DOWN:记录下滑动事件的初始位置。
ACTION_MOVE:根据滑动距离,显示view的位置
ACTION_UP:滑动结束后的操作
2、自定义ListView ,主要控制滑动事件的处理和分发
主要是onTouchEvent方法:
ACTION_DOWN:获取按下时,点击到的是哪个Item,记录下滑动事件的初始位置。
ACTION_MOVE:根据滑动距离,判断滑动:
上下滑动:不作处理,交给listview处理
左右滑动:将滑动事件分发给该Item,并return true,由Item处理滑动事件
ACTION_UP:当时左右滑动时,将滑动事件分发给该Item,并return true,由Item处理滑动事件

---------------------------------------------------------------------

QQ的一个聊天界面的listview每一行向左滑动的时候,会出现删除的按钮,特别炫酷,这个效果可以有,今天跟大家分享下。 
先上demo的效果图 
未滑动的时候的样子 
滑动之后的样子 
界面很丑,因为主要是介绍功能,界面什么的,搞那么复杂,下demo的时候还浪费资源,哈哈哈。

用到的几个类(4个) 
SwipeItemLayout,SwipeListView,SwipeAdapter,FragmentTestActivity. 
SwipeItemLayout就是listView的一个item,这个类集成了FrameLayout。SwipeListView是重写的一个ListView,其实主要在她的OnTouch事件的处理上。SwipeAdapter是一个adapter,这个不用解释了,FragmenTestActivity这个就是怎么用的了。 
好,一个一个来

首先我们看一个item怎么写,先上代码,代码里面基本上有逐行的解释。

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SwipeItemLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FrameLayout</span> {</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个是内容的item,也就是不左滑的时候的布局</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> View contentView = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个是左滑之后显示的那个部分,即多出的部分</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> View menuView = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个是动画的速度控制器,其实没用到</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Interpolator closeInterpolator = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Interpolator openInterpolator = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//控制控件滑动的,会平滑滑动,一个开一个关</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ScrollerCompat mOpenScroller;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ScrollerCompat mCloseScroller;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//左滑之后,contentView左边距离屏幕左边的距离,基线,用于滑回</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mBaseX;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//手指点击的初始位置</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mDownX;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//当前item的状态,open和close两种</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> state = STATE_CLOSE;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> STATE_CLOSE = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> STATE_OPEN = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//构造函数</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">SwipeItemLayout</span>(View contentView,View menuView,Interpolator closeInterpolator, Interpolator openInterpolator){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(contentView.getContext());
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.contentView = contentView;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.menuView = menuView;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.closeInterpolator = closeInterpolator;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.openInterpolator = openInterpolator;

        init();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(){
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置一个item的宽和高,其实就是设置宽充满而已</span>
        setLayoutParams(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT));
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//初始化mColoseScroller和mOpenScroller</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (closeInterpolator != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            mCloseScroller = ScrollerCompat.create(getContext(),
                    closeInterpolator);
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            mCloseScroller = ScrollerCompat.create(getContext());
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (openInterpolator != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            mOpenScroller = ScrollerCompat.create(getContext(),
                    openInterpolator);
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            mOpenScroller = ScrollerCompat.create(getContext());
        }
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这也是设置宽和高</span>
        LayoutParams contentParams = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        contentView.setLayoutParams(contentParams);

        menuView.setLayoutParams(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将这两个布局都add到这个view中</span>
        addView(contentView);
        addView(menuView);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个类就是当用户在界面上滑动的时候,通过ListView的onTouch方法,将MotionEvent的动作传到这里来,通过这个函数执行操作。</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onSwipe</span>(MotionEvent event) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (event.getAction()) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_DOWN:
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//记录当前手指点击的x的坐标</span>
            mDownX = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) event.getX();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_MOVE:
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//当手指移动的时候,获取这个差值</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> dis = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) (mDownX - event.getX());
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个地方,当状态是open的时候,为啥要执行 += 这个操作,我们在下面就会找到答案的</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (state == STATE_OPEN) {
                dis += menuView.getWidth();
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这个函数在下面说</span>
            swipe(dis);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_UP:
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这里其实是一个判断,当用户滑了menuView的一半的时候,自动滑出来,否则滑进去。&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值