1. 程式人生 > >側滑刪除進階(七、八)

側滑刪除進階(七、八)

== tor rri startx Y軸 fin widget posit 調用

技術分享

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.harvic.scrollview_scroller.MainActivity" >

    
    <com.harvic.scrollview_scroller.MyListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

item_layout.xml

<?xml version="1.0" encoding="utf-8"?

> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lin_root" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:minHeight="120dp"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FF83FA" android:gravity="center" android:textSize="25dp" /> <TextView android:id="@+id/del" android:layout_width="200dp" android:layout_height="fill_parent" android:background="#EEEEE0" android:text="刪除" android:textSize="25dp" android:textColor="#ffffff" android:gravity="center" /> </LinearLayout>

MainActivity

package com.harvic.scrollview_scroller;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import com.harvic.scrollview_scroller.MergeListAdapter.DataHolder;


public class MainActivity extends Activity implements View.OnClickListener {

    private MyListView listView;
    private MergeListAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (MyListView)findViewById(R.id.listview);
        final List<DataHolder> items = new ArrayList<DataHolder>();
        for(int i=0;i<20;i++){
            DataHolder item = new DataHolder();
            item.title = "第"+i+"項";
            items.add(item);
        }
        adapter = new MergeListAdapter(this,items,this);
        listView.setAdapter(adapter);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.del){
           int position = listView.getPositionForView(v);
           adapter.removeItem(position);
        }
    }

}

MergeListAdapter

package com.harvic.scrollview_scroller;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by enwei.zew on 2015/4/16.
 */
public class MergeListAdapter extends BaseAdapter {
    private Context mContext;
    private LayoutInflater mInflater;
    private List<DataHolder> mDataList = new ArrayList<DataHolder>();
    private View.OnClickListener mDelClickListener;

    public MergeListAdapter(Context context, List<DataHolder> dataList, View.OnClickListener delClickListener) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        if (dataList != null && dataList.size() > 0) {
            mDataList.addAll(dataList);
        }
        mDelClickListener = delClickListener;
    }

    public void removeItem(int position) {
        mDataList.remove(position);
        notifyDataSetChanged();
    }

    public void addItem(DataHolder item) {
        mDataList.add(item);
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return mDataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null || convertView.getTag() == null) {
            convertView = mInflater.inflate(R.layout.item_layout, parent, false);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        DataHolder item = mDataList.get(position);
        holder.title.setText(item.title);

        item.rootView = (LinearLayout) convertView.findViewById(R.id.lin_root);
        item.rootView.scrollTo(0, 0);


        //點擊刪除實現方法二:交由外部處理:
        TextView delTv = (TextView) convertView.findViewById(R.id.del);
        delTv.setOnClickListener(mDelClickListener);
        return convertView;
    }

    private static class ViewHolder {
        public TextView title;
    }

    public static class DataHolder {
        public String title;
        public LinearLayout rootView;
    }

}


MyListView

package com.harvic.scrollview_scroller;

import com.harvic.scrollview_scroller.MergeListAdapter.DataHolder;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Scroller;

public class MyListView extends ListView {
	// 每一個條目的容器控件
	private LinearLayout itemRoot;
	// 上次手指的x軸坐標
	private int mlastX = 0;
	// 刪除控件的最大寬度
	private final int MAX_WIDTH = 200;
	private Context mContext;
	// scrollTo()是沒有辦法加入運動的時間長度的,所以為了彌補這個問題,google就新增了一個類Scroller!

private Scroller mScroller; public MyListView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; // 創建具有插值器的構造方法 mScroller = new Scroller(context, new LinearInterpolator(context, null)); } @Override public boolean onTouchEvent(MotionEvent event) { int maxLength = dipToPx(mContext, MAX_WIDTH); // 獲取手勢操作觸發的xy軸坐標值 int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { // 我們想知道當前點擊了哪一行 int position = pointToPosition(x, y); if (position != INVALID_POSITION) { // 獲取點擊的item控件的id值 DataHolder data = (DataHolder) getItemAtPosition(position); itemRoot = data.rootView; } } break; case MotionEvent.ACTION_MOVE: { // 獲取item的容器控件在x軸偏移量 int scrollX = itemRoot.getScrollX(); // 實時獲取最新的偏移量 int newScrollX = scrollX + mlastX - x; // 假設手勢向右邊滑動,可能<0 if (newScrollX < 0) { newScrollX = 0; } else if (newScrollX > maxLength) { newScrollX = maxLength; } itemRoot.scrollTo(newScrollX, 0); } break; case MotionEvent.ACTION_UP: { int scrollX = itemRoot.getScrollX(); int newScrollX = scrollX + mlastX - x; if (scrollX > maxLength / 2) { newScrollX = maxLength; } else { newScrollX = 0; } // startScroll(int startX, int startY, int dx, int dy) /** * startX:開始移動的X坐標 startY開始移動的Y坐標 * dx:沿X軸移動距離,可正可負,為正時。子控件向左移動;為負時,子控件向右移動 * dy:沿Y軸移動距離,相同,為正時,子控件向上移動;為負時。子控件向下移動 duration:整個移動過程,所耗費時長 */ mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0); invalidate(); } break; } mlastX = x; return super.onTouchEvent(event); } private int dipToPx(Context context, int dip) { return (int) (dip * context.getResources().getDisplayMetrics().density + 0.5f); } /** * computeScroll()函數。不是Scroller的函數,而是VIEW的函數, * 當調用invaidate或者postInvalidate重繪時就會調用computeScroll() 來重繪與scroller有關的View部分, */ @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { itemRoot.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); } invalidate(); } }


************************************************升級********************************************

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.harvic.scrollviewultimate.MainActivity" >

    <com.harvic.scrollviewultimate.MyListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>
item_layout.xml

<?xml version="1.0" encoding="utf-8"?

> <com.harvic.scrollviewultimate.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lin_root" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:minHeight="120dp"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#0000ff" android:gravity="center" android:textSize="25dp" /> <TextView android:id="@+id/del" android:layout_width="200dp" android:layout_height="fill_parent" android:background="#ffff00" android:text="刪除" android:textSize="25dp" android:textColor="#ffffff" android:gravity="center" /> </com.harvic.scrollviewultimate.MyLinearLayout>


MainActivity
package com.harvic.scrollviewultimate;


import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import com.harvic.scrollviewultimate.MergeListAdapter.DataHolder;

public class MainActivity extends Activity implements View.OnClickListener,MyLinearLayout.OnScrollListener{
    private MyListView listView;
    private MergeListAdapter adapter;
    private MyLinearLayout mLastScrollView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        listView = (MyListView)findViewById(R.id.listview);
        final List<DataHolder> items = new ArrayList<DataHolder>();
        for(int i=0;i<20;i++){
            DataHolder item = new DataHolder();
            item.title = "第"+i+"項";
            items.add(item);
        }
        adapter = new MergeListAdapter(this,items,this,this);
        listView.setAdapter(adapter);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.del){
            int position = listView.getPositionForView(v);
            adapter.removeItem(position);
        }
    }

    @Override
    public void OnScroll(MyLinearLayout view) {
        if (mLastScrollView != null){
            mLastScrollView.smoothScrollTo(0,0);
        }
        mLastScrollView = view;
    }
}

MyListView

package com.harvic.scrollviewultimate;

import com.harvic.scrollviewultimate.MergeListAdapter.DataHolder;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

public class MyListView extends ListView {

    private MyLinearLayout mCurView;
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                int position = pointToPosition(x, y);
                if (position != INVALID_POSITION) {
                    DataHolder data = (DataHolder) getItemAtPosition(position);
                    mCurView = data.rootView;
                }
            }
            break;
            default:
                break;
        }
        if (mCurView != null){
            mCurView.disPatchTouchEvent(event);
        }
        return super.onTouchEvent(event);
    }
}

MergeListAdapter

package com.harvic.scrollviewultimate;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MergeListAdapter extends BaseAdapter {
    private Context mContext;
    private LayoutInflater mInflater;
    private List<DataHolder> mDataList = new ArrayList<DataHolder>();
    private View.OnClickListener mDelClickListener;
    private MyLinearLayout.OnScrollListener mScrollListener;

    public MergeListAdapter(Context context, List<DataHolder> dataList, View.OnClickListener delClickListener,MyLinearLayout.OnScrollListener listener) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        if (dataList != null && dataList.size() > 0) {
            mDataList.addAll(dataList);
        }
        mDelClickListener = delClickListener;
        mScrollListener = listener;
    }

    public void removeItem(int position) {
        mDataList.remove(position);
        notifyDataSetChanged();
    }


    @Override
    public int getCount() {
        return mDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return mDataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null || convertView.getTag() == null) {
            convertView = mInflater.inflate(R.layout.item_layout, parent, false);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        DataHolder item = mDataList.get(position);
        holder.title.setText(item.title);

        item.rootView = (MyLinearLayout) convertView.findViewById(R.id.lin_root);
        item.rootView.scrollTo(0, 0);
        item.rootView.setOnScrollListener(mScrollListener);

        //點擊刪除實現方法二:交由外部處理:
        TextView delTv = (TextView) convertView.findViewById(R.id.del);
        delTv.setOnClickListener(mDelClickListener);
        return convertView;
    }

    private static class ViewHolder {
        public TextView title;
    }

    public static class DataHolder {
        public String title;
        public MyLinearLayout rootView;
    }

}

MyLinearLayout

package com.harvic.scrollviewultimate;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * Created by enwei.zew on 2015/4/28.
 */
public class MyLinearLayout extends LinearLayout {
    private int mlastX = 0;
    private final int MAX_WIDTH = 200;
    private Context mContext;
    private Scroller mScroller;
    private OnScrollListener mScrollListener;

    public static interface OnScrollListener {
        public void OnScroll(MyLinearLayout view);
    }

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mScroller = new Scroller(context, new LinearInterpolator(context, null));
    }

    public void disPatchTouchEvent(MotionEvent event) {
        int maxLength = dipToPx(mContext, MAX_WIDTH);

        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
            }
            break;
            case MotionEvent.ACTION_MOVE: {
                int scrollX = this.getScrollX();
                int newScrollX = scrollX + mlastX - x;
                if (newScrollX < 0) {
                    newScrollX = 0;
                } else if (newScrollX > maxLength) {
                    newScrollX = maxLength;
                }
                this.scrollTo(newScrollX, 0);
            }
            break;
            case MotionEvent.ACTION_UP: {
                int scrollX = this.getScrollX();
                int newScrollX = scrollX + mlastX - x;
                if (scrollX > maxLength / 2) {
                    newScrollX = maxLength;
                    mScrollListener.OnScroll(this);
                } else {
                    newScrollX = 0;
                }
                mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0);
                invalidate();

            }
            break;
        }
        mlastX = x;
    }

    public void setOnScrollListener(OnScrollListener scrollListener) {
        mScrollListener = scrollListener;
    }

    public void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta, 0);
        invalidate();
    }

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

    private int dipToPx(Context context, int dip) {
        return (int) (dip * context.getResources().getDisplayMetrics().density + 0.5f);
    }
}


側滑刪除進階(七、八)