2011.06.20——— android listview的拖拽


参考:http://www.cnblogs.com/qianxudetianxia/archive/2011/06/12/2068761.html


主要看上面那个链接 作者写的非常详细 在此谢过了



可拖拽的listview:

package com.fengjian.test;import android.content.Context;import android.graphics.Bitmap;import android.graphics.PixelFormat;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.ImageView;import android.widget.ListView;import android.widget.Toast;import com.fengjian.test.DragListActivity.DragListAdapter;/** * http://www.cnblogs.com/qianxudetianxia/archive/2011/06/12/2068761.html * @author li * */public class DragListView extends ListView {        private ImageView dragImageView;//被拖拽的项,其实就是一个ImageView    private int dragSrcPosition;//手指拖动项原始在列表中的位置    private int dragPosition;//手指拖动的时候,当前拖动项在列表中的位置        private int dragPoint;//在当前数据项中的位置    private int dragOffset;//当前视图和屏幕的距离(这里只使用了y方向上)        private WindowManager windowManager;//windows窗口控制类    private WindowManager.LayoutParams windowParams;//用于控制拖拽项的显示的参数        private int scaledTouchSlop;//判断滑动的一个距离    private int upScrollBounce;//拖动的时候,开始向上滚动的边界    private int downScrollBounce;//拖动的时候,开始向下滚动的边界        public DragListView(Context context, AttributeSet attrs) {        super(context, attrs);        scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();    }        //拦截touch事件,其实就是加一层控制    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        if(ev.getAction()==MotionEvent.ACTION_DOWN){            int x = (int)ev.getX();            int y = (int)ev.getY();            System.out.println("x: "+ x +" y: "+ y +" RawX: "+ev.getRawX()+" RawY: "+ev.getRawY());            dragSrcPosition = dragPosition = pointToPosition(x, y);//判断当前xy值 是否在item上 如果在 返回改item的position 否则 返回 INVALID_POSITION(-1)            System.out.println("super.onInterceptTouchEvent(ev): "+super.onInterceptTouchEvent(ev));            if(dragPosition==AdapterView.INVALID_POSITION){                return super.onInterceptTouchEvent(ev);            }            System.out.println("dragPosition: "+dragSrcPosition +" getFirstVisiblePosition(): "+getFirstVisiblePosition());                      //getChildAt(int position)参数 为当前屏幕里面显示的item 从0开始 并不是adapter里面的位置 如果当前屏幕显示的微list从 5--8 的数据 则          //getChildAt(0) 为在list中position为5的那个item          //getFirstVisiblePosition()返回第一个显示在界面的view在adapter的位置position,可能是0,也可能是4            ViewGroup itemView = (ViewGroup) getChildAt(dragPosition-getFirstVisiblePosition());            System.out.println("itemView.getTop(): " + itemView.getTop());            dragPoint = y - itemView.getTop();            // lipeng add             //dragPoint = itemView.getTop();            dragOffset = (int) (ev.getRawY() - y);                        View dragger = itemView.findViewById(R.id.drag_list_item_image);            if(dragger!=null&&x>dragger.getLeft()-20){                //                upScrollBounce = Math.min(y-scaledTouchSlop, getHeight()/3);                downScrollBounce = Math.max(y+scaledTouchSlop, getHeight()*2/3);                                itemView.setDrawingCacheEnabled(true);                Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());                startDrag(bm, y);            }            return false;         }         return super.onInterceptTouchEvent(ev);    }    /**     * 触摸事件     */    @Override    public boolean onTouchEvent(MotionEvent ev) {        if(dragImageView!=null&&dragPosition!=INVALID_POSITION){            int action = ev.getAction();            switch(action){                case MotionEvent.ACTION_UP:                    int upY = (int)ev.getY();                    stopDrag();                    onDrop(upY);                    break;                case MotionEvent.ACTION_MOVE:                    int moveY = (int)ev.getY();                    //onDrag(moveY);                    // lipeng add                    onDrag(moveY,(int)ev.getRawY());                    break;                default:break;            }            return true;        }        //也决定了选中的效果        return super.onTouchEvent(ev);    }        /**     * 准备拖动,初始化拖动项的图像     * @param bm     * @param y     */    public void startDrag(Bitmap bm ,int y){        stopDrag();                windowParams = new WindowManager.LayoutParams();        windowParams.gravity = Gravity.TOP;        windowParams.x = 0;                windowParams.y = y - dragPoint + dragOffset;                //windowParams.y = dragPoint + 50;// lipeng add          windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;        windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;        windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE                            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE                            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;        windowParams.format = PixelFormat.TRANSLUCENT;        windowParams.windowAnimations = 0;        ImageView imageView = new ImageView(getContext());        imageView.setImageBitmap(bm);        windowManager = (WindowManager)getContext().getSystemService("window");        windowManager.addView(imageView, windowParams);        dragImageView = imageView;    }        /**     * 停止拖动,去除拖动项的头像     */    public void stopDrag(){        if(dragImageView!=null){            windowManager.removeView(dragImageView);            dragImageView = null;        }    }        /**     * 拖动执行,在Move方法中执行     * @param y     */    public void onDrag(int y){        if(dragImageView!=null){            windowParams.alpha = 0.8f;            windowParams.y = y - dragPoint + dragOffset;            windowManager.updateViewLayout(dragImageView, windowParams);        }        //为了避免滑动到分割线的时候,返回-1的问题        int tempPosition = pointToPosition(0, y);        if(tempPosition!=INVALID_POSITION){            dragPosition = tempPosition;        }                //滚动        int scrollHeight = 0;        if(y<upScrollBounce){            scrollHeight = 8;//定义向上滚动8个像素,如果可以向上滚动的话        }else if(y>downScrollBounce){            scrollHeight = -8;//定义向下滚动8个像素,,如果可以向上滚动的话        }                if(scrollHeight!=0){            //真正滚动的方法setSelectionFromTop()            setSelectionFromTop(dragPosition, getChildAt(dragPosition-getFirstVisiblePosition()).getTop()+scrollHeight);        }    }        // lipeng add {    /**     * 拖动执行,在Move方法中执行     * @param y     */    public void onDrag(int y,int rawY){        if(dragImageView!=null){            windowParams.alpha = 0.8f;            //windowParams.y = y - dragPoint + dragOffset;            windowParams.y = rawY-dragPoint;            windowManager.updateViewLayout(dragImageView, windowParams);        }        //为了避免滑动到分割线的时候,返回-1的问题        int tempPosition = pointToPosition(0, y);        if(tempPosition!=INVALID_POSITION){            dragPosition = tempPosition;        }                //滚动        int scrollHeight = 0;        if(y<upScrollBounce){            scrollHeight = 8;//定义向上滚动8个像素,如果可以向上滚动的话        }else if(y>downScrollBounce){            scrollHeight = -8;//定义向下滚动8个像素,,如果可以向上滚动的话        }                if(scrollHeight!=0){            //真正滚动的方法setSelectionFromTop()            setSelectionFromTop(dragPosition, getChildAt(dragPosition-getFirstVisiblePosition()).getTop()+scrollHeight);        }    }    // lipeng add }        /**     * 拖动放下的时候     * @param y     */    public void onDrop(int y){                //为了避免滑动到分割线的时候,返回-1的问题        int tempPosition = pointToPosition(0, y);        if(tempPosition!=INVALID_POSITION){            dragPosition = tempPosition;        }                //超出边界处理        if(y<getChildAt(1).getTop()){            //超出上边界            dragPosition = 1;        }else if(y>getChildAt(getChildCount()-1).getBottom()){            //超出下边界            dragPosition = getAdapter().getCount()-1;        }                //数据交换        if(dragPosition>0&&dragPosition<getAdapter().getCount()){            DragListAdapter adapter = (DragListAdapter)getAdapter();            String dragItem = adapter.getItem(dragSrcPosition);            adapter.remove(dragItem);            adapter.insert(dragItem, dragPosition);            Toast.makeText(getContext(), adapter.getList().toString(), Toast.LENGTH_SHORT).show();        }            }}


main类:

package com.fengjian.test;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.TextView;public class DragListActivity extends Activity {        private static List<String> list = null;    private DragListAdapter adapter = null;        public static List<String> groupKey= new ArrayList<String>();    private List<String> navList = new ArrayList<String>();    private List<String> moreList = new ArrayList<String>();        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.drag_list_activity);                initData();                DragListView dragListView = (DragListView)findViewById(R.id.drag_list);        adapter = new DragListAdapter(this, list);        dragListView.setAdapter(adapter);    }        public void initData(){        //数据结果        list = new ArrayList<String>();                //groupKey存放的是分组标签        groupKey.add("A组");        groupKey.add("B组");                for(int i=0; i<5; i++){            navList.add("A选项"+i);        }        list.add("A组");        list.addAll(navList);                for(int i=0; i<8; i++){            moreList.add("B选项"+i);        }        list.add("B组");        list.addAll(moreList);    }        public static class DragListAdapter extends ArrayAdapter<String>{        public DragListAdapter(Context context, List<String> objects) {            super(context, 0, objects);        }                public List<String> getList(){            return list;        }                @Override        public boolean isEnabled(int position) {            if(groupKey.contains(getItem(position))){                //如果是分组标签,返回false,不能选中,不能点击                return false;            }            return super.isEnabled(position);        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {                        View view = convertView;            if(groupKey.contains(getItem(position))){                //如果是分组标签,就加载分组标签的布局文件,两个布局文件显示效果不同                view = LayoutInflater.from(getContext()).inflate(R.layout.drag_list_item_tag, null);            }else{                //如果是正常数据项标签,就加在正常数据项的布局文件                view = LayoutInflater.from(getContext()).inflate(R.layout.drag_list_item, null);            }                        TextView textView = (TextView)view.findViewById(R.id.drag_list_item_text);            textView.setText(getItem(position));                        return view;        }    }}



drag_list_activity.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    >    <com.fengjian.test.DragListView        android:id="@+id/drag_list"        android:layout_width="fill_parent"        android:layout_height="fill_parent"       android:cacheColorHint="#00000000"/></LinearLayout>


drag_list_item_tag.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:background="#555555"    android:padding="5dip"    android:paddingLeft="10dip">    <TextView       android:id="@+id/drag_list_item_text"       android:layout_width="wrap_content"       android:layout_height="20dip"       android:textColor="#ffffff"       android:gravity="center_vertical"/></LinearLayout>


drag_list_item.xml

<?xml version="1.0" encoding="utf-8"?><!-- 一定要使用相对布局 --><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content">    <TextView       android:id="@+id/drag_list_item_text"        android:layout_width="wrap_content"        android:layout_height="@dimen/drag_item_normal_height"       android:paddingLeft="5dip"       android:layout_alignParentLeft="true"       android:layout_centerVertical="true"       android:gravity="center_vertical"/>    <ImageView android:id="@+id/drag_list_item_image"       android:src="@drawable/list_icon"       android:layout_alignParentRight="true"       android:layout_centerVertical="true"       android:layout_width="wrap_content"       android:layout_height="@dimen/drag_item_normal_height"/></RelativeLayout>



全部代码 就是上面这些了 截张图吧。。


注意几个问题吧 :

1、pointToPosition(x, y);
判断当前xy值 是否在item上 如果在 返回改item的position 否则 返回 INVALID_POSITION(-1)

2、getChildAt(int position)
参数 为当前屏幕里面显示的item 从0开始 并不是adapter里面的位置 如果当前屏幕显示的微list从 5--8 的数据 则getChildAt(0) 为在list中position为5的那个item
3、getFirstVisiblePosition()
返回第一个显示在界面的view在adapter的位置position,可能是0,也可能是4
4、setSelectionFromTop(position,y)
第一个参数 是需要选中的item的位置,第二个是y轴上的坐标




更多相关文章

  1. android文字滚动
  2. Android中自定义对话框小结
  3. Android中自定义对话框小结
  4. Android点击2次返回按钮退出应用程序
  5. android 左上角返回上一级的实现
  6. Android(安卓)ListView 去除边缘阴影、选中色、拖动背景色、行高
  7. android 竖屏activity跳转横屏activity返回时数据消失
  8. js 判断当前操作系统 ios, android, 电脑端
  9. FregServer进程,发送BC_TRANSACTION,唤醒ServiceManager进程,返回BR

随机推荐

  1. andio:android 音频的代码层次关系
  2. Android(安卓)的 SDK Manager 无法启动
  3. android 程序开发的插件化 模块化方法 之
  4. Android(安卓)恢复出厂设置(recovery)
  5. Android(安卓)ClassLoader解析(2) - Andr
  6. Android(安卓)cupcake源代码获取和编译 f
  7. 学习笔记:原生(android,ios)使用阿里iconf
  8. android web services7
  9. android 屏幕适配问题
  10. 学习android for eclipse