您的位置:首页 > 移动开发 > Android开发

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

2015-04-22 22:43 706 查看
</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"
androi
b889
d: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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: