listview滑动删除

注:前些日子看到在http://www.apkbus.com/forum.php?mod=viewthread&tid=158139&extra=page%3D22的代码,感觉效果不错,遂向其学习而写如下代码,为其精简版,没有楼主的例子完美。以此记录,来记录学习历程,以备后用。

先上图:


在这写下自己的思路:

首先是个listview,但该listview的item左滑的时候,就会出现如图效果。想到应该是自定义的listview,复写其OnTouchEvent方法。那每个listview的item的滑动又是怎么实现的呢?是的,您猜的没错,用的是scroller。

listitem的每个item的xml:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
  
      <LinearLayout
        android:id="@+id/view_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    </LinearLayout>
     <RelativeLayout
        android:id="@+id/holder"
        android:layout_width="120dp"
        android:layout_height="match_parent"
        android:clickable="true"
        android:background="@drawable/holder_bg">


        <TextView
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableLeft="@drawable/del_icon_normal"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:textColor="@color/floralwhite"
            android:text="删除" />
    </RelativeLayout>
</merge>

slideview类:

package com.ryg.slideview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;


public class SlideView extends LinearLayout {

private static final String TAG = "SlideView";
private Context mContext;
private LinearLayout mViewContent;
private RelativeLayout mHolder;
private Scroller mScroller;
private int mHolderWidth = 120;
private int mLastX = 0;
private int mLastY = 0;
private static final int TAN = 2;


public SlideView(Context context) {
super(context);
initView();
}


public SlideView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}


private void initView() {
mContext = getContext();
mScroller = new Scroller(mContext);


setOrientation(LinearLayout.HORIZONTAL);
View.inflate(mContext, R.layout.slide_view_merge, this);
mViewContent = (LinearLayout) findViewById(R.id.view_content);


mHolderWidth = Math.round(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
.getDisplayMetrics()));


// TypedValue.COMPLEX_UNIT_PX,时在不同手机上的数值都是一样的,还是原来数据120.
//
/*
* mHolderWidth = Math.round(TypedValue.applyDimension(
* TypedValue.COMPLEX_UNIT_PX, mHolderWidth, getResources()
* .getDisplayMetrics()));
*/
// TypedValue.COMPLEX_UNIT_DIP在不同手机上显示的是不同的,是独立于设备的。
// 在公司e6机器上显示的是180,在lg上显示240
System.out.println("转化后的mHolderWidth is " + mHolderWidth);
}


public void setButtonText(CharSequence text) {
((TextView) findViewById(R.id.delete)).setText(text);
}


public void setContentView(View view) {
mViewContent.addView(view);
}


public void onRequireTouchEvent(MotionEvent event) {
// 注意执行顺序,每次不同的action都要执行int x=event.getX();和mLastX=x;
// 注意此处的event。getX.越靠左的点x坐标越小,越靠右,x的坐标越大。
int x = (int) event.getX();
int y = (int) event.getY();
System.out.println("event.getX is " + x + "event.getY is --" + y);
// 该处方法是获得滑动了多少距离,根据打印的log。当滑动了180时就不再滑动了
int scrollX = getScrollX();
System.out.println("滑动了多少距离" + scrollX);
Log.d(TAG, "x=" + x + "  y=" + y);


switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("----------down down down down ");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("-----------move move move ");
int deltaX = x - mLastX;
int deltaY = y - mLastY;
System.out.println("----move deltaX is" + deltaX);
if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
break;
}
// 注意这一步的处理,使用的减号
int newScrollX = scrollX - deltaX;
System.out.println("--------newScroll is" + newScrollX);
if (deltaX != 0) {
// 此处为如果复原向右滑则滑动到初始状态,否则滑动到最左
if (newScrollX < 0) {
newScrollX = 0;
} else if (newScrollX > mHolderWidth) {
newScrollX = mHolderWidth;
}
// scrollTo的参数x,若为负数则向右滚动,若为正数则向左滚动
this.scrollTo(newScrollX, 0);
}
break;
case MotionEvent.ACTION_UP:
System.out.println("------------up");
newScrollX = 0;
// 如果已经滑动le0.75倍的距离,则直接滑动到目的地,否则滑动回原来的位置
if (scrollX - mHolderWidth * 0.75 > 0) {
newScrollX = mHolderWidth;
}
this.smoothScrollTo(newScrollX, 0);

break;
default:
break;
}
mLastX = x;
mLastY = y;
System.out.println("---------last x -----" + mLastX);
}


private void smoothScrollTo(int destX, int destY) {
// 缓慢滚动到指定位置
// 返回滚动的view的左边界
int scrollX = getScrollX();
// 在该例子中,当向左滑动时此处的scrollX是正数
System.out.println("scrollX is" + scrollX);
// getScrollX是得到总共滑动的距离,必定为正数
int delta = destX - scrollX;
// startScroll中的参数xofferset如果为正数则向左滑动,yofferset如果为正数则向上滑动
mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
invalidate();
}


@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}


}
现在可以看下listview的适配器中每个item的视图是怎么组织的
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
SlideView slideView = (SlideView) convertView;
if (slideView == null) {
View itemView = mInflater.inflate(R.layout.list_item, null);


slideView = new SlideView(MainActivity.this);
slideView.setContentView(itemView);


holder = new ViewHolder(slideView);
// slideView.setOnSlideListener(MainActivity.this);
slideView.setTag(holder);
} else {
holder = (ViewHolder) slideView.getTag();
}
MessageItem item = mMessageItems.get(position);
item.slideView = slideView;
holder.icon.setImageResource(item.iconRes);
holder.title.setText(item.title);
holder.msg.setText(item.msg);
holder.time.setText(item.time);
holder.deleteHolder.setOnClickListener(MainActivity.this);


return slideView;
}


为什么merge标签会有这种效果呢,还是不是很明白。如果将merge标签换为framelayout则不会有这种视图效果。疑问中。

菜鸟帖子,勿喷。

源码地址:http://download.csdn.net/detail/u010095768/7186465



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值