安卓-ListView側滑刪除
阿新 • • 發佈:2018-11-14
前段時間用到了側滑刪除效果,在網上找了一些資料,結合一些程式碼做了個小測試,先看效果圖
效果圖
思路:ListView裡的每個item做成一個可以滑動的自定義控制元件SlideView,然後時間均又外層的ListView攔截同時把事件傳遞給SlideView做滑動。
下面我畫的一個佈局分佈圖,更方便直觀的看程式碼
下面開始寫程式碼:
SlideView.java 繼承LinearLayout的一個可以滑動的自定義控制元件
package widget.silddelete; 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 com.example.android.activity.R; public class SlideView extends LinearLayout { private static final String TAG = "SlideView"; private Context mContext; private LinearLayout mViewContent; private RelativeLayout mHolder; // Android裡Scroller類是為了實現View平滑滾動的一個Helper類。 // 通常在自定義的View時使用,在View中定義一個私有成員mScroller = new Scroller(context)。 // 設定mScroller滾動的位置時,並不會導致View的滾動, // 通常是用mScroller記錄/計算View滾動的位置,再重寫View的computeScroll(),完成實際的滾動。 private Scroller mScroller; private OnSlideListener mOnSlideListener; private int mHolderWidth = 120; private int mLastX = 0; private int mLastY = 0; private static final int TAN = 2; public interface OnSlideListener { public static final int SLIDE_STATUS_OFF = 0; public static final int SLIDE_STATUS_START_SCROLL = 1; public static final int SLIDE_STATUS_ON = 2; /** * @param view current SlideView * @param status SLIDE_STATUS_ON or SLIDE_STATUS_OFF */ public void onSlide(View view, int status); } public SlideView(Context context) { super(context); initView(); } //自定義控制元件attrs.xml的檔案,並在此檔案中增加對控制元件的屬性的定義 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.item_listview_delete, this); mViewContent = (LinearLayout) findViewById(R.id.view_content); mHolderWidth = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources() .getDisplayMetrics())); } //將view加到ViewContent中去 public void setContentView(View view) { mViewContent.addView(view); } //設定滑動回撥 public void setOnSlideListener(OnSlideListener onSlideListener) { mOnSlideListener = onSlideListener; } public void shrink() { if (getScrollX() != 0) { this.smoothScrollTo(0, 0); } } // 根據MotionEvent來進行滑動,這個方法的作用相當於onTouchEvent // 如果你不需要處理滑動衝突,可以直接重新命名,照樣能正常工作 public void onRequireTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); int scrollX = getScrollX(); Log.d(TAG, "x=" + x + " y=" + y); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } if (mOnSlideListener != null) { mOnSlideListener.onSlide(this, OnSlideListener.SLIDE_STATUS_START_SCROLL); } break; } case MotionEvent.ACTION_MOVE: { int deltaX = x - mLastX; int deltaY = y - mLastY; if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) { // 滑動不滿足條件,不做橫向滑動 break; } // 計算滑動終點是否合法,防止滑動越界 int newScrollX = scrollX - deltaX; if (deltaX != 0) { if (newScrollX < 0) { newScrollX = 0; } else if (newScrollX > mHolderWidth) { newScrollX = mHolderWidth; } this.scrollTo(newScrollX, 0); } break; } case MotionEvent.ACTION_UP: { int newScrollX = 0; if (scrollX - mHolderWidth * 0.75 > 0) { newScrollX = mHolderWidth; } this.smoothScrollTo(newScrollX, 0); if (mOnSlideListener != null) { mOnSlideListener.onSlide(this, newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF : OnSlideListener.SLIDE_STATUS_ON); } break; } default: break; } mLastX = x; mLastY = y; } private void smoothScrollTo(int destX, int destY) { // 緩慢滾動到指定位置 int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } }
ListViewCompat繼承Listview
package widget.silddelete;
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 com.explms.deletelistview.CarListItemModel;
public class ListViewCompat extends ListView {
private static final String TAG = "ListViewCompat";
private SlideView mFocusedItemView;
public ListViewCompat(Context context) {
super(context);
}
public ListViewCompat(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListViewCompat(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
int x = (int) event.getX();
int y = (int) event.getY();
int position = pointToPosition(x, y);
Log.e(TAG, "postion=" + position);
if (position != INVALID_POSITION) {
CarListItemModel data = (CarListItemModel) getItemAtPosition(position);
mFocusedItemView = data.slideView;
Log.e(TAG, "FocusedItemView=" + mFocusedItemView);
}
}
default:
break;
}
if (mFocusedItemView != null) {
mFocusedItemView.onRequireTouchEvent(event);
}
return super.onTouchEvent(event);
}
}
MainActivity.java
package com.explms.deletelistview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import com.example.android.activity.R;
import widget.silddelete.ListViewCompat;
import widget.silddelete.SlideView;
import java.util.ArrayList;
public class MainActivity extends Activity implements SlideView.OnSlideListener {
/**
* Called when the activity is first created.
*/
ListViewCompat popCarListview;
ArrayList<CarListItemModel> poplist;
private SlideView mLastSlideViewWithStatusOn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initview();
}
public void initview() {
popCarListview= (ListViewCompat)findViewById(R.id.car_pop_list);
popCarListview.setAdapter(new PopCarListAdapter(this,getlist()));
}
//<span style="color: rgb(0, 130, 0); font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">向當前點選的view傳送滑動事件請求,其實就是向SlideView發請求</span>
@Override
public void onSlide(View view, int status) {
if (mLastSlideViewWithStatusOn != null && mLastSlideViewWithStatusOn != view) {
mLastSlideViewWithStatusOn.shrink();
}
if (status == SLIDE_STATUS_ON) {
mLastSlideViewWithStatusOn = (SlideView) view;
}
}
public ArrayList<CarListItemModel> getlist(){
poplist=new ArrayList<CarListItemModel>();
for (int i = 0; i < 10; i++) {
CarListItemModel item = new CarListItemModel();
if (i % 2 == 0) {
item.circleImage = R.drawable.img2;
item.productName = "粉紅襯衫";
item.productSize= "S";
item.producrPrice= "25.00";
item.productNumber=""+i;
} else {
item.circleImage = R.drawable.img3;
item.productName = "格子衫";
item.productSize= "M";
item.producrPrice= "65.00";
item.productNumber=""+i;
}
poplist.add(item);
}
return poplist;
}
}
PopCarListAdapter.java listview介面卡
package com.explms.deletelistview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.activity.R;
import widget.silddelete.SlideView;
import java.util.ArrayList;
/**
* Created by Administrator on 7/30/15.
*/
public class PopCarListAdapter extends BaseAdapter{
LayoutInflater inflater;
ArrayList<CarListItemModel> list;
Context context;
public PopCarListAdapter(Context context,ArrayList<CarListItemModel> list){
this.context=context;
this.list=list;
inflater=LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
SlideView slideView = (SlideView) view;
if (slideView == null) {
View itemView = inflater.inflate(R.layout.item_listview_silde, null);
slideView = new SlideView(context);
slideView.setContentView(itemView);
holder = new ViewHolder(slideView);
slideView.setOnSlideListener((SlideView.OnSlideListener) context);
slideView.setTag(holder);
} else {
holder = (ViewHolder) slideView.getTag();
}
CarListItemModel item = list.get(i);
item.slideView = slideView;
item.slideView.shrink();
holder.circleImage.setImageResource(item.circleImage);
holder.productName.setText(item.productName);
holder.productSize.setText(item.productSize);
holder.producrPrice.setText(item.producrPrice);
holder.productNumber.setText(item.productNumber);
holder.deleteHolder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
list.remove(i);
PopCarListAdapter.this.notifyDataSetChanged();
}
});
return slideView;
}
}
class ViewHolder {
public ImageView circleImage;
public TextView productName;
public TextView productSize;
public TextView producrPrice;
public TextView productNumber;
public ViewGroup deleteHolder;
ViewHolder(View view) {
circleImage = (ImageView) view.findViewById(R.id.product_image_circle);
productName= (TextView) view.findViewById(R.id.productname);
productSize = (TextView) view.findViewById(R.id.productsize);
productNumber = (TextView) view.findViewById(R.id.productnumber);
producrPrice= (TextView) view.findViewById(R.id.productprice);
deleteHolder = (ViewGroup)view.findViewById(R.id.holder);
}
}
資料模型CarListItemModel.java
package com.explms.deletelistview;
import widget.silddelete.SlideView;
public class CarListItemModel {
public int circleImage;
public String productName;
public String productSize;
public String producrPrice;
public String productNumber;
public SlideView slideView;
}
另外此博文部分程式碼借鑑http://blog.csdn.net/singwhatiwanna/article/details/17515543,寫的比較清楚,大家可以去看看