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}@Overridepublic 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");/** * 情况一: * * 一个Item的右边布局已经显示, *
* 这时候点击任意一个item, 那么那个右边布局显示的item隐藏其右边布局 */hiddenRight(mPreItemView);}break;}return super.onInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubfloat 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"); /** * 情况二: *
* 一个Item的右边布局已经显示, *
* 这时候左右滑动另外一个item,那个右边布局显示的item隐藏其右边布局 *
* 向左滑动只触发该情况,向右滑动还会触发情况五 */ hiddenRight(mPreItemView); }}else { if (isShown) { Log.i(TAG, "3---> hiddenRight"); /** * 情况三: *
* 一个Item的右边布局已经显示, *
* 这时候上下滚动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"); /** * 情况四: *
* 一个Item的右边布局已经显示, *
* 这时候左右滑动当前一个item,那个右边布局显示的item隐藏其右边布局 */ hiddenRight(mPreItemView); } if (mIsHorizontal) { if (mFirstX - lastX > 30) { showRight(mCurrentItemView); } else { Log.i(TAG, "5---> hiddenRight"); /** * 情况五: *
* 向右滑动一个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 data; /** * @param mainActivity */ public SwipeAdapter(Context ctx,List 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
更多相关文章
- 情况控件Android layout_weight用法图解
- Android中欢迎界面背景图片放大效果
- Android 效果
- 学到一个android小应用-霓虹灯闪烁效果界面
- Android屏幕切换效果实现
- Android 利用TwinklingRefreshLayout 实现下拉效果
- android中动态布局(动态加入TextView和ListView)