Android疯狂ListView之旅 第一季 《侧滑删除条目》


题记 -- --

静坐窗前,细数曾经,捡拾来时路上的点点滴滴,妥帖地收藏,让它们安静地沉睡,等风起的日子,轻轻地唤醒,陪我笑看落花。

落花的窗台,宛若初秋的原野,淌着流动的色彩,像一片片时光打磨的水黑画,定格在岁月的深处,宁静而淡薄。


第一季:《侧滑弹框删除条目操作ListView》

尘世的遇见,若暗夜中划过的流星,寂如烟花,让人欣喜而悲伤

彼岸的花开,涉过烟水寒亭,留下阵阵清香 ...

渐渐的,其实一切都在不然之中... 


图 1-1 
Android疯狂ListView之旅 第一季 《侧滑删除条目》
     


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  点击打开链接查看



上一篇:串口通讯WaitCommEvent 、GetLastError、ClearCommError、...


下一篇:js中的事件委托/代理