Android listView item侧滑实现删除和置顶功能

         第一次写博客,先说下大概思路吧~

        要显示item侧滑显示删除,置顶。首先要隐藏一部分item的布局(自定义隐藏布局宽度,在adapter里设置LayoutParams)。然后重写listview的onInterceptTouchEvent()和onTouchEvent()方法,然后对listview的滑动进行判断,最后进行相应的操作(删除啦,置顶啦,取消置顶bulabula)。删除需要dataList.remove(position),置顶就是将点击的item先执行dataList.add(0,object),然后执行dataList.remove(position),最后adapter.notifyDataSetChanged();先来两张效果图



1.新建attrs.xml,设置好自定义属性(其实就是右边隐藏布局的宽度啦),代码很简单,直接贴上来了


  1. <?xml version=“1.0” encoding=“utf-8”?>  
  2. <resources>  
  3.    
  4.     <declare-styleable name=“slidingitemlistview”>  
  5.         <attr name=“right_width” format=“dimension”></attr>  
  6.     </declare-styleable>  
  7. </resources>  
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="slidingitemlistview">
        <attr name="right_width" format="dimension"></attr>
    </declare-styleable>
</resources>
2.继承listview实现我们自己想要的效果~

(1)第一步在构造方法里获取自定义的宽度(右边局部隐藏的宽度)

  1. public SlidingItemListView(Context context, AttributeSet attrs) {  
  2.     super(context, attrs);  
  3.     TypedArray typedArray = context.obtainStyledAttributes(attrs,  
  4.             R.styleable.slidingitemlistview);  
  5.     mRightViewWidth = (int) typedArray.getDimension(  
  6.             R.styleable.slidingitemlistview_right_width, 200);  
  7.     typedArray.recycle();  
  8.   
  9. }  
 public SlidingItemListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.slidingitemlistview);
        mRightViewWidth = (int) typedArray.getDimension(
                R.styleable.slidingitemlistview_right_width, 200);
        typedArray.recycle();

    }


(2)重写onInterceptTouchEvent()和onTouchEvent()方法,在ACTION_DOWN里获取mCurrentItemView,mPreItemView,mFirstX,mFirstY等。ACTION_UP里对是否在展示做简单的判断,在显示则隐藏。

  1.     @Override  
  2.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  3.         float lastX = ev.getX();  
  4.         float lastY = ev.getY();  
  5.         switch (ev.getAction()) {  
  6.         case MotionEvent.ACTION_DOWN:  
  7.             mIsHorizontal = null;  
  8.             mFirstX = lastX;  
  9.             mFirstY = lastY;  
  10.   
  11.             int position = pointToPosition((int) mFirstX, (int) mFirstY);  
  12.   
  13.             if (position >= 0) {  
  14.                 View view = getChildAt(position - getFirstVisiblePosition());  
  15.                 mPreItemView = mCurrentItemView;  
  16.                 mCurrentItemView = view;  
  17.   
  18.             }  
  19.             Log.i(”TAG”“onInterceptTouchEvent—–>ACTION_DOWN”);  
  20.             break;  
  21.         case MotionEvent.ACTION_MOVE:  
  22.   
  23.             break;  
  24.         case MotionEvent.ACTION_UP:  
  25.             Log.i(”TAG”“onInterceptTouchEvent—–>ACTION_UP”);  
  26.             /**点击隐藏布局会执行MotionEvent.ACTION_UP*/  
  27.             if (mIsShown) {  
  28.                 hideRightView(mCurrentItemView);  
  29.             }  
  30.             break;  
  31.   
  32.         default:  
  33.             break;  
  34.         }  
  35.   
  36.         return super.onInterceptTouchEvent(ev);  
  37.     }  
  38.   
  39.     @Override  
  40.     public boolean onTouchEvent(MotionEvent ev) {  
  41.   
  42.         float lastX = ev.getX();  
  43.         float lastY = ev.getY();  
  44.   
  45.         switch (ev.getAction()) {  
  46.         case MotionEvent.ACTION_DOWN:  
  47.             Log.i(”TAG”“onTouchEvent—->ACTION_DOWN”);  
  48.             break;  
  49.         case MotionEvent.ACTION_MOVE:  
  50.             float dx = lastX - mFirstX;  
  51.             float dy = lastY - mFirstY;  
  52.             Log.i(”TAG”“onTouchEvent—->ACTION_MOVE”);  
  53.   
  54.             if (mIsHorizontal == null) {  
  55.                 if (!judgeScrollDirection(dx, dy)) {  
  56.                     // 没判断出方向  
  57.                     break;  
  58.                 }  
  59.             }  
  60.   
  61.             if (mIsHorizontal) {  
  62.                 if (mIsShown&&mPreItemView!=mCurrentItemView) {  
  63.                     //正在展示,前视图不等于后视图    
  64.                     //则隐藏前视图  
  65.                     hideRightView(mPreItemView);  
  66.                 }  
  67.   
  68.                 // 在mPreItemView!=mCurrentItemView执行 显示隐藏的宽度  
  69.                 if (dx < 0 && dx > -mRightViewWidth) {  
  70.                     Log.i(”TAG”“onTouchEvent—->MOVE   -dx=” + -dx);  
  71.                     mCurrentItemView.scrollTo((int) (-dx), 0);  
  72.                 }  
  73. //               return true;  
  74.             } else {  
  75.                 if (mIsShown) {  
  76.                     //竖直方向滚动  
  77.                     //则隐藏前视图  
  78.                     hideRightView(mPreItemView);  
  79.                 }  
  80.             }  
  81.   
  82.             break;  
  83.         case MotionEvent.ACTION_UP:  
  84.             if (mIsShown) {  
  85.                 //点击时如果有在显示的View  
  86.                 //则隐藏前视图  
  87.                 Log.i(”TAG”“MotionEvent.ACTION_UP 隐藏前视图”);  
  88. //              hideRightView(mCurrentItemView);  
  89.                 hideRightView(mPreItemView);  
  90.             }  
  91.   
  92.             if (mIsHorizontal != null && mIsHorizontal) {  
  93.                 if (mFirstX - lastX > mRightViewWidth / 2) {  
  94.                     showRight(mCurrentItemView);  
  95.                 } else {  
  96.                     // 不到一半则隐藏  
  97.                     hideRightView(mCurrentItemView);  
  98.                 }  
  99.                 Log.i(”TAG”“成功接管OnTouchEvent  CANCLE return TRUE”);  
  100.                  return true;  
  101.             }  
  102.             break;  
  103.   
  104.         default:  
  105.             break;  
  106.         }  
  107.   
  108.         return super.onTouchEvent(ev);  
  109.     }  
  110.   
  111.     /** 
  112.      * 展示隐藏的布局 
  113.      * @param mCurrentItemView2 
  114.      */  
  115.     private void showRight(View mCurrentItemView2) {  
  116.         mCurrentItemView2.scrollTo(mRightViewWidth, 0);  
  117.         mIsShown = true;  
  118.     }  
  119.   
  120.     /**隐藏布局*/  
  121.     private void hideRightView(View mCurrentItemView2) {  
  122.   
  123.         mCurrentItemView2.scrollTo(00);  
  124.           
  125.         mIsShown = false;  
  126.   
  127.     }  
  @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        float lastX = ev.getX();
        float lastY = ev.getY();
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mIsHorizontal = null;
            mFirstX = lastX;
            mFirstY = lastY;

            int position = pointToPosition((int) mFirstX, (int) mFirstY);

            if (position >= 0) {
                View view = getChildAt(position - getFirstVisiblePosition());
                mPreItemView = mCurrentItemView;
                mCurrentItemView = view;

            }
            Log.i("TAG", "onInterceptTouchEvent----->ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:

            break;
        case MotionEvent.ACTION_UP:
            Log.i("TAG", "onInterceptTouchEvent----->ACTION_UP");
            /**点击隐藏布局会执行MotionEvent.ACTION_UP*/
            if (mIsShown) {
                hideRightView(mCurrentItemView);
            }
            break;

        default:
            break;
        }

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        float lastX = ev.getX();
        float lastY = ev.getY();

        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i("TAG", "onTouchEvent---->ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            float dx = lastX - mFirstX;
            float dy = lastY - mFirstY;
            Log.i("TAG", "onTouchEvent---->ACTION_MOVE");

            if (mIsHorizontal == null) {
                if (!judgeScrollDirection(dx, dy)) {
                    // 没判断出方向
                    break;
                }
            }

            if (mIsHorizontal) {
                if (mIsShown&&mPreItemView!=mCurrentItemView) {
                    //正在展示,前视图不等于后视图  
                    //则隐藏前视图
                    hideRightView(mPreItemView);
                }

                // 在mPreItemView!=mCurrentItemView执行 显示隐藏的宽度
                if (dx < 0 && dx > -mRightViewWidth) {
                    Log.i("TAG", "onTouchEvent---->MOVE   -dx=" + -dx);
                    mCurrentItemView.scrollTo((int) (-dx), 0);
                }
//               return true;
            } else {
                if (mIsShown) {
                    //竖直方向滚动
                    //则隐藏前视图
                    hideRightView(mPreItemView);
                }
            }

            break;
        case MotionEvent.ACTION_UP:
            if (mIsShown) {
                //点击时如果有在显示的View
                //则隐藏前视图
                Log.i("TAG", "MotionEvent.ACTION_UP 隐藏前视图");
//              hideRightView(mCurrentItemView);
                hideRightView(mPreItemView);
            }

            if (mIsHorizontal != null && mIsHorizontal) {
                if (mFirstX - lastX > mRightViewWidth / 2) {
                    showRight(mCurrentItemView);
                } else {
                    // 不到一半则隐藏
                    hideRightView(mCurrentItemView);
                }
                Log.i("TAG", "成功接管OnTouchEvent  CANCLE return TRUE");
                 return true;
            }
            break;

        default:
            break;
        }

        return super.onTouchEvent(ev);
    }

    /**
     * 展示隐藏的布局
     * @param mCurrentItemView2
     */
    private void showRight(View mCurrentItemView2) {
        mCurrentItemView2.scrollTo(mRightViewWidth, 0);
        mIsShown = true;
    }

    /**隐藏布局*/
    private void hideRightView(View mCurrentItemView2) {

        mCurrentItemView2.scrollTo(0, 0);

        mIsShown = false;

    }



这里面涉及到一个方法judgeScrollDirection,判断滑动方向,我是这么判断的


  1. <span style=“white-space:pre”>    </span>/** 
  2.      * @param 水平距离差 
  3.      * @param 竖直距离差 
  4.      * @return 水平滑动或者竖直滑动都返回true 没有判断出滑动方向则返回false 
  5.      */  
  6.     private boolean judgeScrollDirection(float dx, float dy) {  
  7.   
  8.         if (Math.abs(dx) > 30 && Math.abs(dx) > Math.abs(dy) * 2) {  
  9.             mIsHorizontal = true;  
  10.             return true;  
  11.         }  
  12.         if (Math.abs(dy) > 30 && Math.abs(dy) > Math.abs(dx) * 2) {  
  13.             mIsHorizontal = false;  
  14.             return true;  
  15.         }  
  16.   
  17.         return false;  
  18.     }  
<span style="white-space:pre">    </span>/**
     * @param 水平距离差
     * @param 竖直距离差
     * @return 水平滑动或者竖直滑动都返回true 没有判断出滑动方向则返回false
     */
    private boolean judgeScrollDirection(float dx, float dy) {

        if (Math.abs(dx) > 30 && Math.abs(dx) > Math.abs(dy) * 2) {
            mIsHorizontal = true;
            return true;
        }
        if (Math.abs(dy) > 30 && Math.abs(dy) > Math.abs(dx) * 2) {
            mIsHorizontal = false;
            return true;
        }

        return false;
    }

(3)啊,最后还有一个get setRightViewWidth方法不要我忘了,后面实例化adapter时还要用

  1. <span style=“white-space:pre”>    </span>public int getRightViewWidth() {  
  2.         return mRightViewWidth;  
  3.     }  
  4.   
  5.     public void setRightViewWidth(int mRightViewWidth) {  
  6.         this.mRightViewWidth = mRightViewWidth;  
  7.     }  
<span style="white-space:pre">   </span>public int getRightViewWidth() {
        return mRightViewWidth;
    }

    public void setRightViewWidth(int mRightViewWidth) {
        this.mRightViewWidth = mRightViewWidth;
    }


自定义listview到此就大功告成了,是不是直接就可以使用了呢?我很负责任的告诉你:绝对不可以!adapter表示自己不乐意!

下面就来写一个adapter吧。继承BaseAdapter重写getCount,getItem,getItemId,getView。当然最重要的是getView。这些比较简单,直接贴代码了

  1. private Context mContext;  
  2.   
  3. private LayoutInflater mInflater;  
  4.   
  5. private List<SlidingItembean> list;  
  6.   
  7. private int mRightViewWidth;  
  8.   
  9. public SlidingItemListViewAdapter(Context mContext,  
  10.         List<SlidingItembean> list, int mRightViewWidth) {  
  11.     super();  
  12.     this.mContext = mContext;  
  13.     this.list = list;  
  14.     this.mRightViewWidth = mRightViewWidth;  
  15.     mInflater = LayoutInflater.from(mContext);  
  16. }  
  17.   
  18. @Override  
  19. public int getCount() {  
  20.     // TODO Auto-generated method stub  
  21.     return list.size();  
  22. }  
  23.   
  24. @Override  
  25. public Object getItem(int position) {  
  26.     // TODO Auto-generated method stub  
  27.     return list.get(position);  
  28. }  
  29.   
  30. @Override  
  31. public long getItemId(int position) {  
  32.     // TODO Auto-generated method stub  
  33.     return position;  
  34. }  
  35.   
  36. @Override  
  37. public View getView(int position, View convertView, ViewGroup parent) {  
  38.   
  39.     ViewHolder viewHolder;  
  40.     onClick listener;  
  41.     if (convertView == null) {  
  42.         convertView = mInflater.inflate(R.layout.item_sliding_listview,  
  43.                 null);  
  44.         viewHolder = new ViewHolder();  
  45.         listener = new onClick();// 实例化  
  46.         viewHolder.Re_left = (RelativeLayout) convertView  
  47.                 .findViewById(R.id.Re_left);  
  48.         viewHolder.ll_right = (LinearLayout) convertView  
  49.                 .findViewById(R.id.ll_right);  
  50.         viewHolder.num = (TextView) convertView  
  51.                 .findViewById(R.id.tv_num_Re_left);  
  52.         viewHolder.name = (TextView) convertView  
  53.                 .findViewById(R.id.tv_name_Re_left);  
  54.         viewHolder.path = (TextView) convertView  
  55.                 .findViewById(R.id.tv_path_Re_left);  
  56.         viewHolder.play = (ImageView) convertView  
  57.                 .findViewById(R.id.img_play_Re_left);  
  58.         viewHolder.setTop= (TextView) convertView.findViewById(R.id.tv_setTop);  
  59.         viewHolder.ll_delete = (LinearLayout) convertView  
  60.                 .findViewById(R.id.ll_delete_ll_right);  
  61.         viewHolder.ll_setTop = (LinearLayout) convertView  
  62.                 .findViewById(R.id.ll_setTop_ll_right);  
  63.         viewHolder.ll_setTop.setOnClickListener(listener);// 监听  
  64.         viewHolder.ll_delete.setOnClickListener(listener);// 监听  
  65.         viewHolder.play.setOnClickListener(listener);// 监听  
  66.         convertView.setTag(viewHolder.play.getId(), listener);// 设置tag  
  67.         convertView.setTag(viewHolder);  
  68.     } else {  
  69.         viewHolder = (ViewHolder) convertView.getTag();  
  70.         listener = (onClick) convertView.getTag(viewHolder.play.getId());// 获取实例  
  71.     }  
  72.   
  73.     listener.setPosition(position);// 传递position  
  74.   
  75.     // 设置布局参数  
  76.   
  77.     LayoutParams lp_left = new LayoutParams(  
  78.             android.widget.LinearLayout.LayoutParams.MATCH_PARENT,  
  79.             android.widget.LinearLayout.LayoutParams.MATCH_PARENT);  
  80.     viewHolder.Re_left.setLayoutParams(lp_left);  
  81.   
  82.     LayoutParams lp_right = new LayoutParams(mRightViewWidth,  
  83.             android.widget.LinearLayout.LayoutParams.MATCH_PARENT);  
  84.     viewHolder.ll_right.setLayoutParams(lp_right);  
  85.   
  86.     SlidingItembean slidingItembean = list.get(position);  
  87.     viewHolder.num.setText(slidingItembean.getNum());  
  88.     viewHolder.name.setText(slidingItembean.getName());  
  89.     viewHolder.path.setText(slidingItembean.getPath());  
  90.     viewHolder.setTop.setText(slidingItembean.getSetTop());  
  91.   
  92.     return convertView;  
  93. }  
 private Context mContext;

    private LayoutInflater mInflater;

    private List<SlidingItembean> list;

    private int mRightViewWidth;

    public SlidingItemListViewAdapter(Context mContext,
            List<SlidingItembean> list, int mRightViewWidth) {
        super();
        this.mContext = mContext;
        this.list = list;
        this.mRightViewWidth = mRightViewWidth;
        mInflater = LayoutInflater.from(mContext);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder;
        onClick listener;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.item_sliding_listview,
                    null);
            viewHolder = new ViewHolder();
            listener = new onClick();// 实例化
            viewHolder.Re_left = (RelativeLayout) convertView
                    .findViewById(R.id.Re_left);
            viewHolder.ll_right = (LinearLayout) convertView
                    .findViewById(R.id.ll_right);
            viewHolder.num = (TextView) convertView
                    .findViewById(R.id.tv_num_Re_left);
            viewHolder.name = (TextView) convertView
                    .findViewById(R.id.tv_name_Re_left);
            viewHolder.path = (TextView) convertView
                    .findViewById(R.id.tv_path_Re_left);
            viewHolder.play = (ImageView) convertView
                    .findViewById(R.id.img_play_Re_left);
            viewHolder.setTop= (TextView) convertView.findViewById(R.id.tv_setTop);
            viewHolder.ll_delete = (LinearLayout) convertView
                    .findViewById(R.id.ll_delete_ll_right);
            viewHolder.ll_setTop = (LinearLayout) convertView
                    .findViewById(R.id.ll_setTop_ll_right);
            viewHolder.ll_setTop.setOnClickListener(listener);// 监听
            viewHolder.ll_delete.setOnClickListener(listener);// 监听
            viewHolder.play.setOnClickListener(listener);// 监听
            convertView.setTag(viewHolder.play.getId(), listener);// 设置tag
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
            listener = (onClick) convertView.getTag(viewHolder.play.getId());// 获取实例
        }

        listener.setPosition(position);// 传递position

        // 设置布局参数

        LayoutParams lp_left = new LayoutParams(
                android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
                android.widget.LinearLayout.LayoutParams.MATCH_PARENT);
        viewHolder.Re_left.setLayoutParams(lp_left);

        LayoutParams lp_right = new LayoutParams(mRightViewWidth,
                android.widget.LinearLayout.LayoutParams.MATCH_PARENT);
        viewHolder.ll_right.setLayoutParams(lp_right);

        SlidingItembean slidingItembean = list.get(position);
        viewHolder.num.setText(slidingItembean.getNum());
        viewHolder.name.setText(slidingItembean.getName());
        viewHolder.path.setText(slidingItembean.getPath());
        viewHolder.setTop.setText(slidingItembean.getSetTop());

        return convertView;
    }
  1. static class ViewHolder {  
  2.   
  3.   
  4. RelativeLayout Re_left;  
  5. LinearLayout ll_right;  
  6.   
  7.   
  8. LinearLayout ll_delete;  
  9. LinearLayout ll_setTop;  
  10.   
  11.   
  12. TextView num;  
  13. TextView name;  
  14. TextView path;  
  15.   
  16.   
  17. ImageView play;  
  18.   
  19.   
  20. TextView setTop;  
  21.    }  
  22.   
  23.   
  24. }  
static class ViewHolder {


RelativeLayout Re_left;
LinearLayout ll_right;


LinearLayout ll_delete;
LinearLayout ll_setTop;


TextView num;
TextView name;
TextView path;


ImageView play;


TextView setTop;
   }


}

 

细心的同学可能会发现onClick 对象,listener。这个listener是干什么的呢?原来啊这是个继承OnClickListener的类,目的和ViewHolder一样,复用item。以前只是复用item控件,这下连监听事件都可以复用了,嘿嘿。代码是不会骗人的,来看看这个Onclick类吧

  1. class onClick implements OnClickListener {  
  2.   
  3.     int position;  
  4.   
  5.     public void setPosition(int position) {  
  6.         this.position = position;  
  7.     }  
  8.   
  9.     @Override  
  10.     public void onClick(View v) {  
  11.         switch (v.getId()) {  
  12.         case R.id.img_play_Re_left:  
  13.             Toast.makeText(mContext, ”play—>position=” + position,  
  14.                     Toast.LENGTH_SHORT).show();  
  15.             break;  
  16.         case R.id.ll_delete_ll_right:  
  17.             list.remove(position);  
  18.             SlidingItemListViewAdapter.this.notifyDataSetChanged();  
  19.   
  20.             break;  
  21.         case R.id.ll_setTop_ll_right:  
  22.   
  23.             if (mySetTopInterface!=null) {  
  24.                 mySetTopInterface.Onclick_ll_setTop_ll_right(v,position);  
  25.             }else {  
  26.                 Toast.makeText(mContext, ”mySetTopInterface==null”,  
  27.                         Toast.LENGTH_SHORT).show();  
  28.             }  
  29.               
  30.             break;  
  31.   
  32.         default:  
  33.             break;  
  34.         }  
  35.   
  36.     }  
  37. }  
   class onClick implements OnClickListener {

        int position;

        public void setPosition(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.img_play_Re_left:
                Toast.makeText(mContext, "play--->position=" + position,
                        Toast.LENGTH_SHORT).show();
                break;
            case R.id.ll_delete_ll_right:
                list.remove(position);
                SlidingItemListViewAdapter.this.notifyDataSetChanged();

                break;
            case R.id.ll_setTop_ll_right:

                if (mySetTopInterface!=null) {
                    mySetTopInterface.Onclick_ll_setTop_ll_right(v,position);
                }else {
                    Toast.makeText(mContext, "mySetTopInterface==null",
                            Toast.LENGTH_SHORT).show();
                }

                break;

            default:
                break;
            }

        }
    }


这里用到了一个自己定义的接口MySetTopInterface,作用显而易见,设置置顶的时候调用此接口,传递两个参数,一个是被点击的View,另一个是position。

  1. MySetTopInterface mySetTopInterface;  
  2.   
  3.     public interface MySetTopInterface {  
  4.         void Onclick_ll_setTop_ll_right(View view,int position);  
  5.     }  
  6.   
  7.     public void setMySetTopInterface(MySetTopInterface mySetTopInterface) {  
  8.         this.mySetTopInterface = mySetTopInterface;  
  9.     }  
MySetTopInterface mySetTopInterface;

    public interface MySetTopInterface {
        void Onclick_ll_setTop_ll_right(View view,int position);
    }

    public void setMySetTopInterface(MySetTopInterface mySetTopInterface) {
        this.mySetTopInterface = mySetTopInterface;
    }
adapter表示自己作用已完成,等待领导指示!

领导表示listview的item布局忘贴上来了,,,
下面贴item_sliding_listview布局,,,

  1. <?xml version=“1.0” encoding=“utf-8”?>  
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  3.     android:layout_width=“match_parent”  
  4.     android:layout_height=“55dp”  
  5.     android:background=“#fff”  
  6.     android:orientation=“horizontal” >  
  7.   
  8.     <RelativeLayout  
  9.         android:id=“@+id/Re_left”  
  10.         android:layout_width=“match_parent”  
  11.         android:layout_height=“match_parent” >  
  12.   
  13.         <TextView  
  14.             android:id=“@+id/tv_num_Re_left”  
  15.             android:layout_width=“20dp”  
  16.             android:layout_height=“20dp”  
  17.             android:layout_centerVertical=“true”  
  18.             android:layout_marginLeft=“10dp”  
  19.             android:layout_marginRight=“10dp”  
  20.             android:background=“@drawable/tv_num_bg”  
  21.             android:gravity=“center”  
  22.             android:text=“1”  
  23.             android:textColor=“#fff”  
  24.             android:textSize=“12sp” />  
  25.   
  26.         <RelativeLayout  
  27.             android:layout_width=“match_parent”  
  28.             android:layout_height=“wrap_content”  
  29.             android:layout_centerVertical=“true”  
  30.             android:layout_toRightOf=“@id/tv_num_Re_left” >  
  31.   
  32.             <TextView  
  33.                 android:id=“@+id/tv_name_Re_left”  
  34.                 android:layout_width=“match_parent”  
  35.                 android:layout_height=“wrap_content”  
  36.                 android:layout_marginBottom=“5dp”  
  37.                 android:text=“《好久不见》”  
  38.                 android:textColor=“#000”  
  39.                 android:textSize=“16sp” />  
  40.   
  41.             <TextView  
  42.                 android:id=“@+id/tv_path_Re_left”  
  43.                 android:layout_width=“match_parent”  
  44.                 android:layout_height=“wrap_content”  
  45.                 android:layout_below=“@id/tv_name_Re_left”  
  46.                 android:text=“/var/mobile/Contalners/Application”  
  47.                 android:textSize=“10sp” />  
  48.         </RelativeLayout>  
  49.   
  50.         <ImageView  
  51.             android:id=“@+id/img_play_Re_left”  
  52.             android:layout_width=“30dp”  
  53.             android:layout_height=“30dp”  
  54.             android:layout_alignParentRight=“true”  
  55.             android:layout_centerVertical=“true”  
  56.             android:layout_marginRight=“10dp”  
  57.             android:scaleType=“fitXY”  
  58.             android:src=“@drawable/wechat_icon” />  
  59.     </RelativeLayout>  
  60.   
  61.     <LinearLayout  
  62.         android:id=“@+id/ll_right”  
  63.         android:layout_width=“wrap_content”  
  64.         android:layout_height=“match_parent”  
  65.         android:orientation=“horizontal” >  
  66.   
  67.         <LinearLayout  
  68.             android:id=“@+id/ll_delete_ll_right”  
  69.             android:layout_width=“0dp”  
  70.             android:layout_height=“match_parent”  
  71.             android:layout_weight=“1”  
  72.             android:background=“#F77D48”  
  73.             android:gravity=“center”  
  74.             android:orientation=“vertical”  
  75.             android:padding=“5dp” >  
  76.   
  77.             <ImageView  
  78.                 android:layout_width=“30dp”  
  79.                 android:layout_height=“30dp”  
  80.                 android:scaleType=“fitXY”  
  81.                 android:src=“@drawable/del_icon_normal” />  
  82.   
  83.             <TextView  
  84.                 android:layout_width=“wrap_content”  
  85.                 android:layout_height=“wrap_content”  
  86.                 android:text=“删除”  
  87.                 android:textColor=“#fff”  
  88.                 android:textSize=“16sp” />  
  89.         </LinearLayout>  
  90.   
  91.         <LinearLayout  
  92.             android:id=“@+id/ll_setTop_ll_right”  
  93.             android:layout_width=“0dp”  
  94.             android:layout_height=“match_parent”  
  95.             android:layout_weight=“1”  
  96.             android:background=“#FED33F”  
  97.             android:gravity=“center”  
  98.             android:orientation=“vertical”  
  99.             android:padding=“5dp” >  
  100.   
  101.             <ImageView  
  102.                 android:layout_width=“30dp”  
  103.                 android:layout_height=“30dp”  
  104.                 android:scaleType=“fitXY”  
  105.                 android:src=“@drawable/qq_icon” />  
  106.   
  107.             <TextView  
  108.                 android:id=“@+id/tv_setTop”  
  109.                 android:layout_width=“wrap_content”  
  110.                 android:layout_height=“wrap_content”  
  111.                 android:text=“置顶”  
  112.                 android:textColor=“#fff”  
  113.                 android:textSize=“12sp” />  
  114.         </LinearLayout>  
  115.     </LinearLayout>  
  116.   
  117. </LinearLayout>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="55dp"
    android:background="#fff"
    android:orientation="horizontal" >

    <RelativeLayout
        android:id="@+id/Re_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/tv_num_Re_left"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/tv_num_bg"
            android:gravity="center"
            android:text="1"
            android:textColor="#fff"
            android:textSize="12sp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/tv_num_Re_left" >

            <TextView
                android:id="@+id/tv_name_Re_left"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:text="《好久不见》"
                android:textColor="#000"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/tv_path_Re_left"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_name_Re_left"
                android:text="/var/mobile/Contalners/Application"
                android:textSize="10sp" />
        </RelativeLayout>

        <ImageView
            android:id="@+id/img_play_Re_left"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:scaleType="fitXY"
            android:src="@drawable/wechat_icon" />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/ll_right"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <LinearLayout
            android:id="@+id/ll_delete_ll_right"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#F77D48"
            android:gravity="center"
            android:orientation="vertical"
            android:padding="5dp" >

            <ImageView
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:scaleType="fitXY"
                android:src="@drawable/del_icon_normal" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="删除"
                android:textColor="#fff"
                android:textSize="16sp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_setTop_ll_right"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FED33F"
            android:gravity="center"
            android:orientation="vertical"
            android:padding="5dp" >

            <ImageView
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:scaleType="fitXY"
                android:src="@drawable/qq_icon" />

            <TextView
                android:id="@+id/tv_setTop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="置顶"
                android:textColor="#fff"
                android:textSize="12sp" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


至此,listview的初始化算完事了。

下面来看看怎么应用吧(实现item置顶,取消置顶)

(1)在activity_main.xml里添加自定义的listview。其中  xmlns:dyk=”http://schemas.Android.com/apk/res/com.example.qqslidingitem”为自定义命名空间

  1. <com.example.qqslidingitem.SlidingItemListView  
  2.        xmlns:dyk=“http://schemas.android.com/apk/res/com.example.qqslidingitem”  
  3.        android:id=“@+id/listview”  
  4.        android:layout_width=“match_parent”  
  5.        android:layout_height=“match_parent”  
  6.        android:background=“#fff4f7f9”  
  7.        android:cacheColorHint=“#00000000”  
  8.        android:divider=“#dddbdb”  
  9.        android:dividerHeight=“1dp”  
  10.        dyk:right_width=“120dp” />  
 <com.example.qqslidingitem.SlidingItemListView
        xmlns:dyk="http://schemas.android.com/apk/res/com.example.qqslidingitem"
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff4f7f9"
        android:cacheColorHint="#00000000"
        android:divider="#dddbdb"
        android:dividerHeight="1dp"
        dyk:right_width="120dp" />
(2)接下来就该实现刚留的MySetTopInterface接口,复写Onclick_ll_setTop_ll_right方法。(初始化工作直接贴代码)

  1. <span style=“white-space:pre”>    </span>private SlidingItemListView mListView;  
  2.     private SlidingItemListViewAdapter adapter;  
  3.     private List<SlidingItembean> list = new ArrayList<SlidingItembean>();  
  4.   
  5.   
  6.     @Override  
  7.     protected void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         // requestWindowFeature(Window.FEATURE_NO_TITLE);  
  10.         setContentView(R.layout.activity_main);  
  11.         initView();  
  12.         initData();  
  13.         initEvent();  
  14.   
  15.     }  
  16.   
  17.     private void initEvent() {  
  18.         adapter = new SlidingItemListViewAdapter(MainActivity.this, list,  
  19.                 mListView.getRightViewWidth());  
  20.         mListView.setAdapter(adapter);  
  21.         adapter.setMySetTopInterface(this);  
  22.         // mListView.setSelection(position);  
  23.   
  24.         mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  25.             @Override  
  26.             public void onItemClick(AdapterView<?> parent, View view,  
  27.                     int position, long id) {  
  28.                 Toast.makeText(MainActivity.this,  
  29.                         ”item onclick ” + list.get(position).getNum(),  
  30.                         Toast.LENGTH_SHORT).show();  
  31.             }  
  32.         });  
  33.     }  
  34.   
  35.     private void initData() {  
  36.         for (int i = 0; i < 50; i++) {  
  37.             SlidingItembean slidingItembean = null;  
  38.             if (i % 3 == 0) {  
  39.                 slidingItembean = new SlidingItembean(String.valueOf(i),  
  40.                         ”你会不会忽然的出现”“/var/mobile/Contalners/Application”,  
  41.                         ”置顶”);  
  42.             } else if (i % 3 == 1) {  
  43.                 slidingItembean = new SlidingItembean(String.valueOf(i),  
  44.                         ”在街角的咖啡店”“/var/mobile/Contalners/Application”,  
  45.                         ”置顶”);  
  46.             } else {  
  47.                 slidingItembean = new SlidingItembean(String.valueOf(i),  
  48.                         ”我会带着笑脸,和你,坐着聊聊天”“/var/mobile/Contalners/Application”,  
  49.                         ”置顶”);  
  50.             }  
  51.   
  52.             list.add(slidingItembean);  
  53.         }  
  54.     }  
  55.   
  56.     /** 
  57.      * 初始化界面 
  58.      */  
  59.     private void initView() {  
  60.         mListView = (SlidingItemListView) findViewById(R.id.listview);  
  61.   
  62.     }  
<span style="white-space:pre">    </span>private SlidingItemListView mListView;
    private SlidingItemListViewAdapter adapter;
    private List<SlidingItembean> list = new ArrayList<SlidingItembean>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initEvent();

    }

    private void initEvent() {
        adapter = new SlidingItemListViewAdapter(MainActivity.this, list,
                mListView.getRightViewWidth());
        mListView.setAdapter(adapter);
        adapter.setMySetTopInterface(this);
        // mListView.setSelection(position);

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

    private void initData() {
        for (int i = 0; i < 50; i++) {
            SlidingItembean slidingItembean = null;
            if (i % 3 == 0) {
                slidingItembean = new SlidingItembean(String.valueOf(i),
                        "你会不会忽然的出现", "/var/mobile/Contalners/Application",
                        "置顶");
            } else if (i % 3 == 1) {
                slidingItembean = new SlidingItembean(String.valueOf(i),
                        "在街角的咖啡店", "/var/mobile/Contalners/Application",
                        "置顶");
            } else {
                slidingItembean = new SlidingItembean(String.valueOf(i),
                        "我会带着笑脸,和你,坐着聊聊天", "/var/mobile/Contalners/Application",
                        "置顶");
            }

            list.add(slidingItembean);
        }
    }

    /**
     * 初始化界面
     */
    private void initView() {
        mListView = (SlidingItemListView) findViewById(R.id.listview);

    }


接下来重点完成置顶和取消置顶功能~

  1. @Override  
  2.     public void Onclick_ll_setTop_ll_right(View view, int position) {  
  3.   
  4.         if (list.get(position).getSetTop().equals(“置顶”)) {  
  5.   
  6.             setTop(position);  
  7.   
  8.         } else if (list.get(position).getSetTop().equals(“取消置顶”)) {  
  9.   
  10.             unSetTop(position);  
  11.   
  12.         }  
  13.   
  14.     }  
@Override
    public void Onclick_ll_setTop_ll_right(View view, int position) {

        if (list.get(position).getSetTop().equals("置顶")) {

            setTop(position);

        } else if (list.get(position).getSetTop().equals("取消置顶")) {

            unSetTop(position);

        }

    }


置顶setTop

  1. <span style=“white-space:pre”>    </span>/** 
  2.      * 置顶 
  3.      * @param position 
  4.      */  
  5.     private void setTop(int position) {  
  6.         list.get(position).setSetTop(”取消置顶”);  
  7.         list.add(0, list.get(position));  
  8.         // 置顶后list.size增加一 所以要position+1  
  9.         list.remove(position + 1);  
  10.         adapter.notifyDataSetChanged();  
  11.     }  
<span style="white-space:pre">    </span>/**
     * 置顶
     * @param position
     */
    private void setTop(int position) {
        list.get(position).setSetTop("取消置顶");
        list.add(0, list.get(position));
        // 置顶后list.size增加一 所以要position+1
        list.remove(position + 1);
        adapter.notifyDataSetChanged();
    }


取消置顶我采用的策略是先遍历datalist,然后找到前一项比他小后一项比他大的位置然后插入。细心的同学会发现这样写有一个小小的bug要是选择项就是最小的没法处理,所以会有些特殊情况要单独拿出来讨论。

  1. <span style=“white-space:pre”>    </span>/** 
  2.      * 取消置顶 
  3.      * @param position 
  4.      */  
  5.     private void unSetTop(int position) {  
  6.         boolean isAdd = false;  
  7.         /** 差值 */  
  8.         int min = 9999999;  
  9.         /** 当前position的数值 */  
  10.         int num;  
  11.         // 差值最小处的行数  
  12.         int j = 0;  
  13.         int num2 = 0;  
  14.         int jumpNum = 0;  
  15.         list.get(position).setSetTop(”置顶”);  
  16.         num = Integer.parseInt(list.get(position).getNum());  
  17.         // list长度为2特殊处理  
  18.         if (list.size() == 2) {  
  19.             // 第一行确定为取消置顶  
  20.             if (list.get(1).getSetTop().equals(“取消置顶”)) {  
  21.                 if (position == 0) {  
  22.                     if (num == 0) {  
  23.                         list.add(2, list.get(position));  
  24.                     }  
  25.                     if (num == 1) {  
  26.                         list.add(2, list.get(position));  
  27.                     }  
  28.                     list.remove(position);  
  29.                     adapter.notifyDataSetChanged();  
  30.                 } else {  
  31.                     list.add(2, list.get(position));  
  32.                     list.remove(position);  
  33.                     adapter.notifyDataSetChanged();  
  34.                 }  
  35.             } else {  
  36.                 if (num == 0) {  
  37.                     list.add(1, list.get(position));  
  38.                 }  
  39.                 if (num == 1) {  
  40.                     list.add(2, list.get(position));  
  41.                 }  
  42.                 list.remove(position);  
  43.                 adapter.notifyDataSetChanged();  
  44.             }  
  45.         } else {  
  46.   
  47.             for (int i = 0; i < list.size(); i++) {  
  48.   
  49.                 if (num > Integer.parseInt(list.get(i).getNum())  
  50.                         && num < Integer.parseInt(list.get(i + 1).getNum())) {  
  51.                     list.add(i + 1, list.get(position));  
  52.                     isAdd = true;  
  53.                     break;  
  54.                 }  
  55.             }  
  56.   
  57.             // 如果没有比自己小的值 例如0 则isAdd=false  
  58.             // 遍历list 寻找差值最小的地方插入list  
  59.             if (!isAdd) {  
  60.                 for (int i = 0; i < list.size(); i++) {  
  61.   
  62.                     if (i == position || list.get(i).getSetTop().equals(“取消置顶”)) {  
  63.                         // 排除与自身相比较  
  64.                         // 排除置顶item比较  
  65.                         Log.i(”TAG”“调过” + i);  
  66.                         jumpNum++;  
  67.                         if (jumpNum == list.size()) {  
  68.                             j = list.size();  
  69.                         }  
  70.   
  71.                         continue;  
  72.                     }  
  73.   
  74.                     num2 = Integer.parseInt(list.get(i).getNum());  
  75.                     if (num2 - num < min) {  
  76.                         min = num2 - num;  
  77.                         // 记录行号  
  78.                         j = i;  
  79.                         Log.i(”TAG”“插入行数J=” + j);  
  80.                     }  
  81.                 }  
  82.                 // 遍历完成后拿到差值min  
  83.                 int number = min + num;  
  84.                 list.add(j, list.get(position));  
  85.                 Log.i(”TAG”“*********插入行数J=” + j);  
  86.             }  
  87.   
  88.             list.remove(position);  
  89.             adapter.notifyDataSetChanged();  
  90.         }  
  91.   
  92.     }  
<span style="white-space:pre"> </span>/**
     * 取消置顶
     * @param position
     */
    private void unSetTop(int position) {
        boolean isAdd = false;
        /** 差值 */
        int min = 9999999;
        /** 当前position的数值 */
        int num;
        // 差值最小处的行数
        int j = 0;
        int num2 = 0;
        int jumpNum = 0;
        list.get(position).setSetTop("置顶");
        num = Integer.parseInt(list.get(position).getNum());
        // list长度为2特殊处理
        if (list.size() == 2) {
            // 第一行确定为取消置顶
            if (list.get(1).getSetTop().equals("取消置顶")) {
                if (position == 0) {
                    if (num == 0) {
                        list.add(2, list.get(position));
                    }
                    if (num == 1) {
                        list.add(2, list.get(position));
                    }
                    list.remove(position);
                    adapter.notifyDataSetChanged();
                } else {
                    list.add(2, list.get(position));
                    list.remove(position);
                    adapter.notifyDataSetChanged();
                }
            } else {
                if (num == 0) {
                    list.add(1, list.get(position));
                }
                if (num == 1) {
                    list.add(2, list.get(position));
                }
                list.remove(position);
                adapter.notifyDataSetChanged();
            }
        } else {

            for (int i = 0; i < list.size(); i++) {

                if (num > Integer.parseInt(list.get(i).getNum())
                        && num < Integer.parseInt(list.get(i + 1).getNum())) {
                    list.add(i + 1, list.get(position));
                    isAdd = true;
                    break;
                }
            }

            // 如果没有比自己小的值 例如0 则isAdd=false
            // 遍历list 寻找差值最小的地方插入list
            if (!isAdd) {
                for (int i = 0; i < list.size(); i++) {

                    if (i == position || list.get(i).getSetTop().equals("取消置顶")) {
                        // 排除与自身相比较
                        // 排除置顶item比较
                        Log.i("TAG", "调过" + i);
                        jumpNum++;
                        if (jumpNum == list.size()) {
                            j = list.size();
                        }

                        continue;
                    }

                    num2 = Integer.parseInt(list.get(i).getNum());
                    if (num2 - num < min) {
                        min = num2 - num;
                        // 记录行号
                        j = i;
                        Log.i("TAG", "插入行数J=" + j);
                    }
                }
                // 遍历完成后拿到差值min
                int number = min + num;
                list.add(j, list.get(position));
                Log.i("TAG", "*********插入行数J=" + j);
            }

            list.remove(position);
            adapter.notifyDataSetChanged();
        }

    }

 

大功告成!接下来做一个小总结吧。首先是自定义属性,其次是对布局隐藏的处理,第三是对getView中item的复用,最后是对自定义接口中删除,置顶,取消置顶功能实现的处理。第一次写的博客,不好的地方请谅解。



源码下载http://download.csdn.net/detail/qq_17250009/9228877

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值