1. 程式人生 > >安卓-ListView側滑刪除

安卓-ListView側滑刪除

   前段時間用到了側滑刪除效果,在網上找了一些資料,結合一些程式碼做了個小測試,先看效果圖

     效果圖

                                       

   思路: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,寫的比較清楚,大家可以去看看