仿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
- 仿QQ滑动删除
- 仿qq滑动删除
- Android 仿QQ 滑动删除
- recyclerview仿qq滑动删除
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- 仿qq的listView 滑动删除
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- ListView滑动删除 ,仿腾讯QQ
- 仿qq向左滑动删除 案例 详解
- ListView滑动删除 ,仿腾讯QQ
- Android仿QQ实现ListView滑动删除
- ListView滑动删除 ,仿腾讯QQ
- oracle查询锁表,并解锁sql
- Cocos2d-x Lua中帧动画
- 根据年月以及月中周次,获取该周开始,结束日期
- linux命令之——sed用法
- 9.2 qt creator 创建工程遇到的低级错误
- 仿qq滑动删除
- 理解RPC和LPC的概念
- Leetcode212-Word Search II
- unity RPC网络传输
- SDUT 2073----活动选择问题
- List进行remove和add操作时缘何会报UnsupportedOperationException
- P124 第48题 排序
- Jedis操作redis
- Android ListView使用BaseAdapter与ListView的优化