Android仿QQ消息列表ListView滑动删除效果

之前一篇文章中介绍了微信滑动删除效果(Android 仿微信对话列表滑动删除效果),这一篇在其基础上实现QQ消息列表ListView滑动删除效果,大致原理差不多,这里就不细说了。


运行效果如下:









SwipeListView.java

package com.example.swipelistview.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.example.swipelistview.R;

public class SwipeListView extends ListView {

	private static final String TAG = SwipeListView.class.getSimpleName();

	private boolean isShown;

	private View mPreItemView;

	private View mCurrentItemView;

	private float mFirstX;

	private float mFirstY;

	private boolean mIsHorizontal;

	public SwipeListView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public SwipeListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public SwipeListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		float lastX = ev.getX();
		float lastY = ev.getY();
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:

			mIsHorizontal = false;
			
			mFirstX = lastX;
			mFirstY = lastY;
			int motionPosition = pointToPosition((int) mFirstX, (int) mFirstY);

			Log.e(TAG, "onInterceptTouchEvent----->ACTION_DOWN position=" + motionPosition);
			
			if (motionPosition >= 0) {
				View currentItemView = getChildAt(motionPosition - getFirstVisiblePosition());
				mPreItemView = mCurrentItemView;
				mCurrentItemView = currentItemView;
			}
			break;

		case MotionEvent.ACTION_MOVE:
			float dx = lastX - mFirstX;
			float dy = lastY - mFirstY;

			if (Math.abs(dx) >= 5 && Math.abs(dy) >= 5) {
				return true;
			}
			break;

		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:

			Log.i(TAG, "onInterceptTouchEvent----->ACTION_UP");
			if (isShown && mPreItemView != mCurrentItemView) {
				Log.i(TAG, "1---> hiddenRight");
				/**
                 * 情况一:
                 * <p>
                 * 一个Item的右边布局已经显示,
                 * <p>
                 * 这时候点击任意一个item, 那么那个右边布局显示的item隐藏其右边布局
                 */
				hiddenRight(mPreItemView);
			}
			break;
		}

		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		float lastX = ev.getX();
		float lastY = ev.getY();

		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i(TAG, "---->ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			float dx = lastX - mFirstX;
			float dy = lastY - mFirstY;

			mIsHorizontal = isHorizontalDirectionScroll(dx, dy);
			
			if (!mIsHorizontal) {
				break;
			}

			Log.i(TAG, "onTouchEvent ACTION_MOVE");
			
			if (mIsHorizontal) {
                if (isShown && mPreItemView != mCurrentItemView) {
                	Log.i(TAG, "2---> hiddenRight");
                    /**
                     * 情况二:
                     * <p>
                     * 一个Item的右边布局已经显示,
                     * <p>
                     * 这时候左右滑动另外一个item,那个右边布局显示的item隐藏其右边布局
                     * <p>
                     * 向左滑动只触发该情况,向右滑动还会触发情况五
                     */
                    hiddenRight(mPreItemView);
                }
			}else {
                if (isShown) {
                	Log.i(TAG, "3---> hiddenRight");
                    /**
                     * 情况三:
                     * <p>
                     * 一个Item的右边布局已经显示,
                     * <p>
                     * 这时候上下滚动ListView,那么那个右边布局显示的item隐藏其右边布局
                     */
                    hiddenRight(mPreItemView);
                }
            }
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			Log.i(TAG, "============ACTION_UP");
			if (isShown) {
				Log.i(TAG, "4---> hiddenRight");
                /**
                 * 情况四:
                 * <p>
                 * 一个Item的右边布局已经显示,
                 * <p>
                 * 这时候左右滑动当前一个item,那个右边布局显示的item隐藏其右边布局
                 */
                hiddenRight(mPreItemView);
            }

            if (mIsHorizontal) {
                if (mFirstX - lastX > 30) {
                    showRight(mCurrentItemView);
                } else {
                	Log.i(TAG, "5---> hiddenRight");
                    /**
                     * 情况五:
                     * <p>
                     * 向右滑动一个item,且滑动的距离超过了右边View的宽度的一半,隐藏之。
                     */
                    hiddenRight(mCurrentItemView);
                }
                return true;
            }
			break;
		}

		return super.onTouchEvent(ev);
	}

	private void showRight(View rightView) {
		RelativeLayout rl_right=(RelativeLayout)rightView.findViewById(R.id.item_right);
		rl_right.setVisibility(View.VISIBLE);
		
		isShown = true;
	}
	
	private void hiddenRight(View rightView) {
		
		RelativeLayout rl_right=(RelativeLayout)rightView.findViewById(R.id.item_right);
		rl_right.setVisibility(View.GONE);
		
		isShown = false;
	}

	/**
	 * @param dx
	 * @param dy
	 * @return judge if can judge scroll direction
	 */
	private boolean isHorizontalDirectionScroll(float dx, float dy) {
		boolean mIsHorizontal = true;

		if (Math.abs(dx) > 30 && Math.abs(dx) > 2 * Math.abs(dy)) {
			mIsHorizontal = true;
			System.out.println("mIsHorizontal---->" + mIsHorizontal);
		} else if (Math.abs(dy) > 30 && Math.abs(dy) > 2 * Math.abs(dx)) {
			mIsHorizontal = false;
			System.out.println("mIsHorizontal---->" + mIsHorizontal);
		}

		return mIsHorizontal;
	}
	
}


SwipeAdapter.java

package com.example.swipelistview.adapter;

import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.swipelistview.R;
import com.example.swipelistview.entity.WXMessage;

public class SwipeAdapter extends BaseAdapter {
    /**
     * 上下文对象
     */
    private Context mContext = null;
    private List<WXMessage> data;
    
    /**
     * @param mainActivity
     */
    public SwipeAdapter(Context ctx,List<WXMessage> data) {
        mContext = ctx;
        this.data = data;
    }

    @Override
    public int getCount() {
//      return 100;
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
    	
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
            holder = new ViewHolder();
            holder.item_left = (RelativeLayout)convertView.findViewById(R.id.item_left);
            holder.item_right = (RelativeLayout)convertView.findViewById(R.id.item_right);
            
            holder.iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);
            holder.tv_title = (TextView)convertView.findViewById(R.id.tv_title);
            holder.tv_msg = (TextView)convertView.findViewById(R.id.tv_msg);
            holder.tv_time = (TextView)convertView.findViewById(R.id.tv_time);
            
            holder.item_right_txt = (TextView)convertView.findViewById(R.id.item_right_txt);
            convertView.setTag(holder);
        } else {// 有直接获得ViewHolder
            holder = (ViewHolder)convertView.getTag();
        }
        
        Log.i("SwipeAdapter", "getView position="+position);
        
        WXMessage msg = data.get(position);
        
        holder.tv_title.setText(msg.getTitle());
        holder.tv_msg.setText(msg.getMsg());
        holder.tv_time.setText(msg.getTime());
        
        holder.iv_icon.setImageResource(msg.getIcon_id());
        
        holder.item_right.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onRightItemClick(v, position);
                }
            }
        });
        return convertView;
    }

    static class ViewHolder {
    	RelativeLayout item_left;
    	RelativeLayout item_right;

        TextView tv_title;
        TextView tv_msg;
        TextView tv_time;
        ImageView iv_icon;

        TextView item_right_txt;
    }
    
    /**
     * 单击事件监听器
     */
    private onRightItemClickListener mListener = null;
    
    public void setOnRightItemClickListener(onRightItemClickListener listener){
    	mListener = listener;
    }

    public interface onRightItemClickListener {
        void onRightItemClick(View v, int position);
    }
}




Demo下载地址:http://download.csdn.net/detail/fx_sky/6913747





  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值