ANDROID 动态添加的listView,仿QQ滑动删除

</pre>想实现一个仿QQ滑动删除的dome<p></p><p>百度了一下,在JAVAAPK网上下了一个例子大全,在里面找了一个例子,我就直接用了。</p><p>若有版权问题,请私信我,秒删。</p><p>下面写一些自己使用的过程,帮助自己记忆。</p><p></p><pre name="code" class="java">import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Scroller;

public class SlideCutListView extends ListView {
	private int slidePosition, preSlidePosition;
	private int downY;
	private int downX;
	public static View itemView, preItemView;
	private Scroller scroller;
	private static final int SNAP_VELOCITY = 600;
	private VelocityTracker velocityTracker;
	public static boolean isSlide = false;
	private boolean isResponse = true;
	public static boolean isObstruct = true;
	private int mTouchSlop;
	private RemoveListener mRemoveListener;
	private AddListener mAddListener;

	private static Animation scaleHideAnimation;
	private static Animation scaleShowAnimation;

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

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

	public SlideCutListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		scroller = new Scroller(context);
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
	}

	public void setRemoveListener(RemoveListener removeListener) {
		this.mRemoveListener = removeListener;
	}
	public void setAddListener(AddListener addListener){
		this.mAddListener=addListener;
	}

	public boolean dispatchTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: {

			Log.e("sunzn", "dispatchTouchEvent ACTION_DOWN isSlide = " + isSlide);

			addVelocityTracker(event);

			downX = (int) event.getX();
			downY = (int) event.getY();

			slidePosition = pointToPosition(downX, downY);

			if (slidePosition == AdapterView.INVALID_POSITION) {
				return super.dispatchTouchEvent(event);
			}

			if (preItemView != null && preItemView.findViewById(R.id.tv_coating).getVisibility() == View.GONE) {
				itemView = preItemView;
				slidePosition = preSlidePosition;
			} else {
				itemView = getChildAt(slidePosition - getFirstVisiblePosition());
				preItemView = itemView;
				preSlidePosition = slidePosition;
			}

			break;
		}
		case MotionEvent.ACTION_MOVE: {
			if (Math.abs(getScrollVelocity()) > SNAP_VELOCITY || (Math.abs(event.getX() - downX) > mTouchSlop && Math.abs(event.getY() - downY) < mTouchSlop)) {
				isSlide = true;
			}
			break;
		}
		case MotionEvent.ACTION_UP:
			recycleVelocityTracker();
			isObstruct = true;
			break;
		}

		return super.dispatchTouchEvent(event);
	}

	public boolean onInterceptTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_MOVE:
			if (itemView.findViewById(R.id.tv_coating).getVisibility() == View.VISIBLE) {
				isSlide = false;
			} else {
				isSlide = true;
			}
			break;

		default:
			break;
		}
		return super.onInterceptTouchEvent(ev);
	}

	public boolean onTouchEvent(MotionEvent ev) {
		if (isSlide && slidePosition != AdapterView.INVALID_POSITION) {
			addVelocityTracker(ev);
			final int action = ev.getAction();
			switch (action) {
			case MotionEvent.ACTION_MOVE:
				Log.e("sunzn", "onTouchEvent ACTION_MOVE isSlide = " + isSlide);
				if (isObstruct) {

					if (itemView.findViewById(R.id.tv_coating).getVisibility() == View.VISIBLE && isResponse == true) {

						scaleHideAnimation = new ScaleAnimation(1.0f, 0.0f, 1.0f, 1.0f);
						scaleHideAnimation.setDuration(250);
						scaleHideAnimation.setAnimationListener(new AnimationListener() {

							public void onAnimationStart(Animation animation) {
								isResponse = false;
								isObstruct = false;
							}

							public void onAnimationRepeat(Animation animation) {

							}

							public void onAnimationEnd(Animation animation) {
								isResponse = true;
								itemView.findViewById(R.id.tv_coating).setVisibility(View.GONE);
								itemView.findViewById(R.id.tv_functions).setClickable(true);
								itemView.findViewById(R.id.tv_functions).setOnClickListener(new OnClickListener() {

									public void onClick(View v) {
										mRemoveListener.removeItem(slidePosition);
									}

								});

							}
						});

						itemView.findViewById(R.id.tv_coating).startAnimation(scaleHideAnimation);

					} else if (itemView.findViewById(R.id.tv_coating).getVisibility() == View.GONE && isResponse == true) {

						scaleShowAnimation = new ScaleAnimation(0.0f, 1.0f, 1.0f, 1.0f);
						scaleShowAnimation.setDuration(250);
						scaleShowAnimation.setAnimationListener(new AnimationListener() {

							public void onAnimationStart(Animation animation) {
								isResponse = false;
								isObstruct = false;
							}

							public void onAnimationRepeat(Animation animation) {

							}

							public void onAnimationEnd(Animation animation) {
								isSlide = false;
								isResponse = true;
								itemView.findViewById(R.id.tv_coating).setVisibility(View.VISIBLE);
							}
						});

						itemView.findViewById(R.id.tv_coating).startAnimation(scaleShowAnimation);
					}
				}
				break;
			case MotionEvent.ACTION_UP:
				isObstruct = true;
				recycleVelocityTracker();
				isSlide = true;
				break;
			}
			return true;
		}

		return super.onTouchEvent(ev);
	}

	public void computeScroll() {
		if (scroller.computeScrollOffset()) {
			postInvalidate();
			if (scroller.isFinished()) {
				if (mRemoveListener == null) {
					throw new NullPointerException("RemoveListener is null, we should called setRemoveListener()");
				}

				itemView.scrollTo(0, 0);
			}
		}
	}

	private void addVelocityTracker(MotionEvent event) {
		if (velocityTracker == null) {
			velocityTracker = VelocityTracker.obtain();
		}
		velocityTracker.addMovement(event);
	}

	private void recycleVelocityTracker() {
		if (velocityTracker != null) {
			velocityTracker.recycle();
			velocityTracker = null;
		}
	}

	private int getScrollVelocity() {
		velocityTracker.computeCurrentVelocity(1000);
		int velocity = (int) velocityTracker.getXVelocity();
		return velocity;
	}

	public interface RemoveListener {
		public void removeItem(int position);
	}
	public interface AddListener{
		public void addItem(int position);
	}
	
}
看起来很多东西,但是我们用起来并不复杂

下面贴上xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    android:gravity="center"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:gravity="center"            <span style="color:#ff0000;">这里就是item的主内容</span>
        android:textSize="25sp"
        android:text="ITEM" />

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"                            <span style="color:#ff0000;">这是放删除button的,布局有点奇怪,下面两个textview其实是重叠的,第一个就红色删除b                                                                  utton,在第二个textview上面做动画。这样做的有没有必要我还不了解,我现在就拿来用了。</span>
        android:layout_gravity="right|center_vertical"
        android:background="@android:color/darker_gray"
        android:padding="15dp" >

        <TextView
            android:id="@+id/tv_functions"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:background="@drawable/btn_del_bg"
            android:gravity="center"
            android:text="@string/del"
            android:textColor="@android:color/white" />

        <TextView
            android:id="@+id/tv_coating"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:background="@android:color/darker_gray"
            android:visibility="gone" />
    </FrameLayout>

</LinearLayout>

XML第一个TextView可以自己定义,第二个是放删除BUTTON的,图片和文字可以自己改。

下面放mainactivity

布局很简单,上面一个button,下面就放一个lsitview,注意吧包名打全

<com.example.slidecut.SlideCutListView
        android:layout_marginTop="15dp"
        android:id="@+id/slideCutListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@drawable/reader_item_divider" >
    </com.example.slidecut.SlideCutListView>
然后贴上java

import java.util.ArrayList;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.view.View.OnClickListener;
import com.example.slidecut.SlideCutListView.AddListener;
import com.example.slidecut.SlideCutListView.RemoveListener;


public class MainActivity extends ActionBarActivity implements RemoveListener{
	private SlideCutListView slideCutListView;
	private ArrayList<String> dataSourceList = new ArrayList<String>();
	private ArrayList<String> extra = new ArrayList<String>();

	private ItemAdapter adapter;
	private Button addButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inti();
    }


    private void inti() {
		// TODO Auto-generated method stub
    	slideCutListView = (SlideCutListView) findViewById(R.id.slideCutListView);
    	slideCutListView.setRemoveListener(this);
//    	记得setadapter
    	for (int i = 0; i < 20; i++) {
			dataSourceList.add((i > 9 ? "ITEM" + " " + i : "ITEM" + " 0" + i));
		}
    	adapter = new ItemAdapter(this);
		adapter.setData(dataSourceList);//这里放进去数据
		slideCutListView.setAdapter(adapter);//这里把listviewset一个adapter
		
		addButton=(Button) findViewById(R.id.id_add);
		
		
		addButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				dataSourceList.add("qwer");
				adapter.notifyDataSetChanged();
			}
		});
			
		
		
	}
    

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    
 


	@Override
	public void removeItem(int position) {
		SlideCutListView.isSlide = false;
		SlideCutListView.itemView.findViewById(R.id.tv_coating).setVisibility(View.VISIBLE);
<span style="background-color: rgb(255, 255, 255);">	</span><span style="background-color: rgb(255, 102, 102);">	dataSourceList.remove(position);
		adapter.notifyDataSetChanged();
		    <span style="white-space: pre;">					</span>这里就实现用remove方法,传入一个int值,就是list的行数,然后把他remove掉。这里用的是我们定义那个</span>
<span style="background-color: rgb(255, 102, 102);"><span style="white-space: pre;">							</span>list类的接口。</span><span style="background-color: rgb(255, 255, 255);">
	}</span><span style="white-space: pre; background-color: rgb(255, 255, 255);">	</span><span style="background-color: rgb(255, 255, 255);">



	
}
</span>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值