仿qq滑动删除

来源:互联网 发布:淘宝客qq群拉人技巧 编辑:程序博客网 时间:2024/06/09 16:43

本文是通过http://blog.csdn.net/top_code/article/details/17965743讲解的仿qq滑动删除进行修改进而达到更类似qq滑动删除的效果,

想要更详细的了解本文,建议先看看http://blog.csdn.net/top_code/article/details/17965743这个,

与他主要不同就是我定义了一个接口点击删除的时候执行接口的onDeleteItemClick()方法

接口如下

package com.fxsky.swipelist.interfaces;


public interface DeleteClickListener {
void onDeleteItemClick();
}

然后修改他自定义的listview


package com.fxsky.swipelist.widget;


import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;


import com.fxsky.swipelist.R;
import com.fxsky.swipelist.interfaces.DeleteClickListener;


public class SwipeListView extends ListView implements DeleteClickListener{
    private Boolean mIsHorizontal;


    private View mPreItemView;


    private View mCurrentItemView;


    private float mFirstX;


    private float mFirstY;


    private int mRightViewWidth;


    // private boolean mIsInAnimation = false;
    private final int mDuration = 100;


    private final int mDurationStep = 10;


    private boolean mIsShown;


    public SwipeListView(Context context) {
        this(context,null);
    }


    public SwipeListView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }


    public SwipeListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,  
                R.styleable.swipelistviewstyle);  
        
      //获取自定义属性和默认值  
      mRightViewWidth = (int) mTypedArray.getDimension(R.styleable.swipelistviewstyle_right_width, 200);   
      
      mTypedArray.recycle();  
    }


    /**
     * return true, deliver to listView. return false, deliver to child. if
     * move, return true
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        float lastX = ev.getX();
        float lastY = ev.getY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsHorizontal = null;
                System.out.println("onInterceptTouchEvent----->ACTION_DOWN");
                mFirstX = lastX;
                mFirstY = lastY;
                int motionPosition = pointToPosition((int)mFirstX, (int)mFirstY);


                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:
                System.out.println("onInterceptTouchEvent----->ACTION_UP");
                if (mIsShown && (mPreItemView != mCurrentItemView || isHitCurItemLeft(lastX))) {
                    System.out.println("1---> hiddenRight");
                    /**
                     * 情况一:
                     * <p>
                     * 一个Item的右边布局已经显示,
                     * <p>
                     * 这时候点击任意一个item, 那么那个右边布局显示的item隐藏其右边布局
                     */
                    hiddenRight(mPreItemView);
                }
                break;
        }


        return super.onInterceptTouchEvent(ev);
    }


    private boolean isHitCurItemLeft(float x) {
        return x < getWidth() - mRightViewWidth;
    }


    /**
     * @param dx
     * @param dy
     * @return judge if can judge scroll direction
     */
    private boolean judgeScrollDirection(float dx, float dy) {
        boolean canJudge = 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);
        } else {
            canJudge = false;
        }


        return canJudge;
    }


    /**
     * return false, can't move any direction. return true, cant't move
     * vertical, can move horizontal. return super.onTouchEvent(ev), can move
     * both.
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        float lastX = ev.getX();
        float lastY = ev.getY();


        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                System.out.println("---->ACTION_DOWN");
                break;


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


                // confirm is scroll direction
                if (mIsHorizontal == null) {
                    if (!judgeScrollDirection(dx, dy)) {
                        break;
                    }
                }


                if (mIsHorizontal) {
                    if (mIsShown && mPreItemView != mCurrentItemView) {
                        System.out.println("2---> hiddenRight");
                        /**
                         * 情况二:
                         * <p>
                         * 一个Item的右边布局已经显示,
                         * <p>
                         * 这时候左右滑动另外一个item,那个右边布局显示的item隐藏其右边布局
                         * <p>
                         * 向左滑动只触发该情况,向右滑动还会触发情况五
                         */
                        hiddenRight(mPreItemView);
                    }


                    if (mIsShown && mPreItemView == mCurrentItemView) {
                        dx = dx - mRightViewWidth;
                        System.out.println("======dx " + dx);
                    }


                    // can't move beyond boundary
                    if (dx < 0 && dx > -mRightViewWidth) {
                        mCurrentItemView.scrollTo((int)(-dx), 0);
                    }


                    return true;
                } else {
                    if (mIsShown) {
                        System.out.println("3---> hiddenRight");
                        /**
                         * 情况三:
                         * <p>
                         * 一个Item的右边布局已经显示,
                         * <p>
                         * 这时候上下滚动ListView,那么那个右边布局显示的item隐藏其右边布局
                         */
                        hiddenRight(mPreItemView);
                    }
                }


                break;


            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                System.out.println("============ACTION_UP");
                clearPressedState();
                if (mIsShown) {
                    System.out.println("4---> hiddenRight");
                    /**
                     * 情况四:
                     * <p>
                     * 一个Item的右边布局已经显示,
                     * <p>
                     * 这时候左右滑动当前一个item,那个右边布局显示的item隐藏其右边布局
                     */
                    hiddenRight(mPreItemView);
                }


                if (mIsHorizontal != null && mIsHorizontal) {
                    if (mFirstX - lastX > mRightViewWidth / 2) {
                        showRight(mCurrentItemView);
                    } else {
                        System.out.println("5---> hiddenRight");
                        /**
                         * 情况五:
                         * <p>
                         * 向右滑动一个item,且滑动的距离超过了右边View的宽度的一半,隐藏之。
                         */
                        hiddenRight(mCurrentItemView);
                    }


                    return true;
                }


                break;
        }


        return super.onTouchEvent(ev);
    }


    private void clearPressedState() {
        // TODO current item is still has background, issue
        mCurrentItemView.setPressed(false);
        setPressed(false);
        refreshDrawableState();
        // invalidate();
    }


    private void showRight(View view) {
        System.out.println("=========showRight");


        Message msg = new MoveHandler().obtainMessage();
        msg.obj = view;
        msg.arg1 = view.getScrollX();
        msg.arg2 = mRightViewWidth;
        msg.sendToTarget();


        mIsShown = true;
    }


    private void hiddenRight(View view) {
        System.out.println("=========hiddenRight");
        if (mCurrentItemView == null) {
            return;
        }
        Message msg = new MoveHandler().obtainMessage();//
        msg.obj = view;
        msg.arg1 = view.getScrollX();
        msg.arg2 = 0;


        msg.sendToTarget();


        mIsShown = false;
    }


    /**
     * show or hide right layout animation
     */
    @SuppressLint("HandlerLeak")
    class MoveHandler extends Handler {
        int stepX = 0;


        int fromX;


        int toX;


        View view;


        private boolean mIsInAnimation = false;


        private void animatioOver() {
            mIsInAnimation = false;
            stepX = 0;
        }


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (stepX == 0) {
                if (mIsInAnimation) {
                    return;
                }
                mIsInAnimation = true;
                view = (View)msg.obj;
                fromX = msg.arg1;
                toX = msg.arg2;
                stepX = (int)((toX - fromX) * mDurationStep * 1.0 / mDuration);
                if (stepX < 0 && stepX > -1) {
                    stepX = -1;
                } else if (stepX > 0 && stepX < 1) {
                    stepX = 1;
                }
                if (Math.abs(toX - fromX) < 10) {
                    view.scrollTo(toX, 0);
                    animatioOver();
                    return;
                }
            }


            fromX += stepX;
            boolean isLastStep = (stepX > 0 && fromX > toX) || (stepX < 0 && fromX < toX);
            if (isLastStep) {
                fromX = toX;
            }


            view.scrollTo(fromX, 0);
            invalidate();


            if (!isLastStep) {
                this.sendEmptyMessageDelayed(0, mDurationStep);
            } else {
                animatioOver();
            }
        }
    }


    public int getRightViewWidth() {
        return mRightViewWidth;
    }


    public void setRightViewWidth(int mRightViewWidth) {
        this.mRightViewWidth = mRightViewWidth;
    }


@Override
public void onDeleteItemClick() {
hiddenRight(mPreItemView);
}
}

主要就是让他自定义的listView实现DeleteClickListener这个接口

然后在接口的onDeleteItemtClick()方法中调用他的hiddenRight(mPreItemView)方法也就是隐藏删除按钮

接着在他的适配器里面修改代码



package com.fxsky.swipelist.adapter;


import java.util.List;


import android.content.Context;
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.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;


import com.fxsky.swipelist.R;
import com.fxsky.swipelist.entity.WXMessage;
import com.fxsky.swipelist.interfaces.DeleteClickListener;
import com.fxsky.swipelist.widget.SwipeListView;


public class SwipeAdapter extends BaseAdapter {
    /**
     * 上下文对象
     */
    private Context mContext = null;
    private List<WXMessage> data;
    
    private int mRightWidth = 0;
    
    private SwipeListView swipeListView;


    /**
     * @param mainActivity
     */
    public SwipeAdapter(Context ctx,List<WXMessage> data, int rightWidth,SwipeListView swipeListView) {
        mContext = ctx;
        this.data = data;
        this.swipeListView = swipeListView;
        mRightWidth = rightWidth;
    }


    @Override
    public int getCount() {
        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();
        }
        
        LinearLayout.LayoutParams lp1 = new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT);
        holder.item_left.setLayoutParams(lp1);
        LinearLayout.LayoutParams lp2 = new LayoutParams(mRightWidth, LayoutParams.MATCH_PARENT);
        holder.item_right.setLayoutParams(lp2);
        
        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 (swipeListView instanceof DeleteClickListener) {
            data.remove(position);
            swipeListView.onDeleteItemClick();
                notifyDataSetChanged();
}
            }
        });
        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;
    }
}

首先构造函数中添加一个参数

就是传入自定义的ListView对象。

然后在点击删除按钮的时候


实现DeleteClickListener 接口的onDeleteItemClick();

然后删除对应项,通知list更新。

下面看看效果


写不好,请谅解,嘿嘿

源码下载链接:http://download.csdn.net/detail/kai_1215/8727293

0 0