1. 程式人生 > >Android瘋狂ListView之旅 第一季 《側滑刪除條目》

Android瘋狂ListView之旅 第一季 《側滑刪除條目》

題記 -- --

靜坐窗前,細數曾經,撿拾來時路上的點點滴滴,妥帖地收藏,讓它們安靜地沉睡,等風起的日子,輕輕地喚醒,陪我笑看落花。

落花的窗臺,宛若初秋的原野,淌著流動的色彩,像一片片時光打磨的水黑畫,定格在歲月的深處,寧靜而淡薄。

第一季:《側滑彈框刪除條目操作ListView》

塵世的遇見,若暗夜中劃過的流星,寂如煙花,讓人欣喜而悲傷

彼岸的花開,涉過煙水寒亭,留下陣陣清香 ...

漸漸的,其實一切都在不然之中... 

圖 1-1 
     
public class PopButonListView extends ListView {


    private int mTouchSlop;

    /**
     * 彈出的pop控制系列
     */
    private LayoutInflater mInflater;
    private  PopupWindow mPopupWindow;
    private int mPopupWindowHeight;
    private int mPopupWindowWidth;
    private Button mDelBtn;
    /**
     * 當前點選的位置
     */
    private int mCurrentItemPostion;
    /**
     *  上一次點選的位置
     *  當其中的一個item條目的刪除按鈕為顯示狀態的時候,當再次點選的時候,我們需要將顯示的那個按鈕進行隱藏,這裡涉及到事件的向下傳遞分配
     *  當點選的為同一個條目的時候,我們需要將事件進行攔截,也就是說刪除按鈕為顯示,再次點選將刪除按鈕進行隱藏
     *  當點選的不為同一個條目的時候,我們需要將上一個條目顯示出來的刪除按鈕進行隱藏,然後將事件向下傳遞,在新點選滑動的位置彈出新的刪除按鈕
     */
    private int mPreItemPostion;
    public PopButonListView(Context context) {
        super(context);
        init(context);
    }
    

    public PopButonListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public PopButonListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    private void init(Context context) {

        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        /**
         * 初始化pop使用到的相關內容
         */
        mInflater = LayoutInflater.from(context);
        View view = mInflater.inflate(R.layout.delete_btn, null);
        mDelBtn = (Button) view.findViewById(R.id.id_item_btn);
        mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);



        /**
         * 先呼叫下measure,否則拿不到寬和高
         */
        mPopupWindow.getContentView().measure(0, 0);
        mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight();
        mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();
    }

    /**
     * 是否需要彈出標識
     * true 彈出 從右向左滑動
     * false 不彈出
     *
     */
    private boolean isSliding;

    /**
     * 當前按下的ListView 條目
     */
    private View mCurrentItemView;

    /**
     * 記錄手指按下時的座標位置 
     */
    private int downX;
    private int downY;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        int x =(int)ev.getX();
        int y=(int)ev.getY();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                downX = x;
                downY = y;

                /**
                 * 獲取手按下條目的位置
                 */
                mCurrentItemPostion = this.pointToPosition(downX, downY);
                /**
                 *  獲得當前手指按下時的item
                 */
                View view = getChildAt(mCurrentItemPostion - getFirstVisiblePosition());
                mCurrentItemView = view;


                /**
                 * 如果當前條目的popupWindow顯示,則直接隱藏,然後遮蔽ListView的touch事件的下傳
                 * 如果 popupWindow 顯示,點選其他的item ,隱藏當前的pop,繼續其他操作
                 */
                if (mPopupWindow.isShowing())
                {
                    dismissPopWindow();
                    if (mCurrentItemPostion==mPreItemPostion) {
                        return false;
                    }
                }

                if (mCurrentItemPostion!=mPreItemPostion){
                    mPreItemPostion = mCurrentItemPostion;
                }

                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int)ev.getX();
                int moveY = (int)ev.getY();

                int flagX = moveX - downX;
                int flagY = moveY - downY;
                /**
                 * 判斷是否是從右到左的滑動
                 * moveX <downX
                 */
                if (moveX < downX && Math.abs(flagX) > mTouchSlop && Math.abs(flagY) < mTouchSlop)
                {
                    isSliding = true;
                }
                break;

        }

        return super.dispatchTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        int action = ev.getAction();
        /**
         * 如果是從右到左的滑動才相應
         * isSliding 為true
         */
        if (isSliding)
        {
            switch (action)
            {
                case MotionEvent.ACTION_MOVE:

                    int[] location = new int[2];
                    /**
                     * 獲得當前item的位置x與y
                     */
                    mCurrentItemView.getLocationOnScreen(location);
                    /**
                     *設定popupWindow的動畫
                     */
                    mPopupWindow.setAnimationStyle(R.style.anim_popup_dir);

                    mPopupWindow.showAtLocation(mCurrentItemView, Gravity.LEFT | Gravity.TOP,
                            location[0] + mCurrentItemView.getWidth(), location[1] + mCurrentItemView.getHeight() / 2
                                    - mPopupWindowHeight / 2 );
                    /**
                     * 設定刪除按鈕的回撥
                     * 在這裡只是說明了一個方法原理,當然可以擴充套件更多的按鈕與相關的操作
                     */
                    mDelBtn.setOnClickListener(new OnClickListener()
                    {
                        @Override
                        public void onClick(View v)
                        {
                            if (mListener != null)
                            {
                                mListener.onItemDeletClick(mCurrentItemPostion);
                                mPopupWindow.dismiss();
                            }
                        }
                    });

                    break;
                case MotionEvent.ACTION_UP:
                    isSliding = false;

            }
            // 相應滑動期間螢幕itemClick事件,避免發生衝突
            return true;
        }

        return super.onTouchEvent(ev);
    }
    /**
     * 隱藏popupWindow
     */
    private void dismissPopWindow()
    {
        if (mPopupWindow != null && mPopupWindow.isShowing())
        {
            mPopupWindow.dismiss();
        }
    }
    public interface OnListItemDeletButtonListerner{
        public void onItemDeletClick(int postion);
    }
    /**
     * 定義刪除按鈕點選事件的監聽
     */
    private OnListItemDeletButtonListerner mListener;

    public void setOnListItemDeletButtonListerner(OnListItemDeletButtonListerner listItemDeletButtonListerner){
        this.mListener = listItemDeletButtonListerner;
    }
}




public class DeleteButtonActivity extends AppCompatActivity {

    private PopButonListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overridePendingTransition(R.anim.activity_enter_anim, R.anim.activity_exit_anim);
        setContentView(R.layout.activity_deletbutton);
        mListView = (PopButonListView) findViewById(R.id.popbutonlistv);

        final List mDatas = new ArrayList<String>();
        for (int i = 0; i < 15; i++) {
            mDatas.add("how are you ? \t" + i);
        }
        final ArrayAdapter mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDatas);
        mListView.setAdapter(mAdapter);

        mListView.setOnListItemDeletButtonListerner(new PopButonListView.OnListItemDeletButtonListerner() {
            @Override
            public void onItemDeletClick(int postion) {

                mDatas.remove(postion);
                mAdapter.notifyDataSetChanged();
            }
        });

        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(DeleteButtonActivity.this, position + " : ", Toast.LENGTH_SHORT).show();
            }
        });
    }

}


安靜的聆聽,安靜的行走,看細碎的陽光,若雪花一樣在深秋中紛給墜落,期待冬雪,來埋藏所有的悲與痛,待來時的雪融化,春暖花開。

第二季 26英文字母分組排序顯示資料 ListView 

第三季  自定義下拉重新整理操作的 ListView