draggable可拖动的ListView,并且支持行删除功能

来源:互联网 发布:外国文学杂志知乎 编辑:程序博客网 时间:2024/05/17 22:26
看图,拖动前:

拖动后:


package com.ql.view;import com.ql.activity.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.PixelFormat;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;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;/** * draggable可拖动的列表,并且支持行删除功能 * @author admin * */public class DraggableListView extends ListView {private DropListener mDropListener;private ImageView mDragView;private int mDragPos; // which item is being draggedprivate int mFirstDragPos; // where was the dragged item originallyprivate int mDragPoint; // at what offset inside the item did the user grab// itprivate int mCoordOffset; // the difference between screen coordinates and// coordinates in this viewprivate Rect mTempRect = new Rect();private final int mTouchSlop;private int mHeight;private int mUpperBound;private int mLowerBound;private WindowManager mWindowManager;private WindowManager.LayoutParams mWindowParams;private int dragndropBackgroundColor = 0x00000000;private Bitmap mDragBitmap;private int mItemHeightHalf = 32;private int mItemHeightNormal = 64;private int mItemHeightExpanded = 128;//private int grabberId=-1;public DraggableListView(Context context, AttributeSet attrs) {this(context, attrs, 0);// TODO Auto-generated constructor stub}public DraggableListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubmTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();//if (attrs!=null) {//TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.TouchListView,0, 0);////mItemHeightNormal=a.getDimensionPixelSize(R.styleable.TouchListView_normal_height, 0);//mItemHeightExpanded=a.getDimensionPixelSize(R.styleable.TouchListView_expanded_height, mItemHeightNormal);//grabberId=a.getResourceId(R.styleable.TouchListView_grabber, -1);//dragndropBackgroundColor=a.getColor(R.styleable.TouchListView_dragndrop_background, 0x00000000);////mRemoveMode=a.getInt(R.styleable.TouchListView_remove_mode, -1);////a.recycle();//}}@Overridepublic boolean onTouchEvent(MotionEvent ev) {// TODO Auto-generated method stub//Log.v(">>>>>>>>>>onTouchEvent", ">>>>>>>>>>onTouchEvent");if ((mDropListener != null) && mDragView != null) {int action = ev.getAction();switch (action) {case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:Rect r = mTempRect;mDragView.getDrawingRect(r);stopDragging();if (mDropListener != null && mDragPos >= 0&& mDragPos < getCount()) {mDropListener.drop(mFirstDragPos, mDragPos);}unExpandViews(false);break;case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:int x = (int) ev.getX();int y = (int) ev.getY();dragView(x, y);int itemnum = getItemForPosition(y);if (itemnum >= 0) {if (action == MotionEvent.ACTION_DOWN|| itemnum != mDragPos) {mDragPos = itemnum;doExpansion();//Log.v(">>>doExpansion", ">>>>>>>>>>doExpansion");}/*int speed = 0;adjustScrollBounds(y);if (y > mLowerBound) {// scroll the list up a bitspeed = y > (mHeight + mLowerBound) / 2 ? 16 : 4;} else if (y < mUpperBound) {// scroll the list down a bitspeed = y < mUpperBound / 2 ? -16 : -4;}if (speed != 0) {int ref = pointToPosition(0, mHeight / 2);if (ref == AdapterView.INVALID_POSITION) {// we hit a divider or an invisible view, check// somewhere elseref = pointToPosition(0, mHeight / 2+ getDividerHeight() + 64);}View v = getChildAt(ref - getFirstVisiblePosition());if (v != null) {int pos = v.getTop();setSelectionFromTop(ref, pos - speed);}}*/}break;}return true;}return super.onTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubif (mDropListener != null) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:int x = (int) ev.getX();int y = (int) ev.getY();int itemnum = pointToPosition(x, y);//Log.v("itemnum>>>", ">>>>>>>>" + itemnum);if (itemnum == AdapterView.INVALID_POSITION) {break;}ViewGroup item = (ViewGroup) getChildAt(itemnum- getFirstVisiblePosition());//Log.v("itemnum>>>", ">>>>>>>>" + getFirstVisiblePosition()//+ "---" + ev.getRawY() + "----" + ev.getY()+"-----"+item.getTop());mDragPoint = y - item.getTop();mCoordOffset = ((int) ev.getRawY()) - y;View dragger = item.findViewById(R.id.iconimg);//拖动的ImageViewRect r = mTempRect;// dragger.getDrawingRect(r);r.left = dragger.getLeft();r.right = dragger.getRight();r.top = dragger.getTop();r.bottom = dragger.getBottom();if ((r.left < x) && (x < r.right)) {item.setDrawingCacheEnabled(true);// Create a copy of the drawing cache so that it does not// get recycled// by the framework when the list tries to clean up memoryBitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());startDragging(bitmap, y);mDragPos = itemnum;mFirstDragPos = mDragPos;mHeight = getHeight();int touchSlop = mTouchSlop;mUpperBound = Math.min(y - touchSlop, mHeight / 3);mLowerBound = Math.max(y + touchSlop, mHeight * 2 / 3);return false;}//View delView = item.findViewById(R.id.delete);//删除的ImageViewr.left = delView.getLeft();r.right = delView.getRight();r.top = delView.getTop();r.bottom = delView.getBottom();if ((r.left < x) && (x < r.right)) {mDropListener.onDeleteClicked(itemnum);return false;}mDragView = null;break;}}return super.onInterceptTouchEvent(ev);}private void startDragging(Bitmap bm, int y) {stopDragging();mWindowParams = new WindowManager.LayoutParams();mWindowParams.gravity = Gravity.TOP;mWindowParams.x = 0;mWindowParams.y = y - mDragPoint + mCoordOffset;mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;mWindowParams.format = PixelFormat.TRANSLUCENT;mWindowParams.windowAnimations = 0;ImageView v = new ImageView(getContext());// int backGroundColor =// getContext().getResources().getColor(R.color.dragndrop_background);v.setBackgroundColor(dragndropBackgroundColor);v.setImageBitmap(bm);mDragBitmap = bm;mWindowManager = (WindowManager) getContext().getSystemService("window");mWindowManager.addView(v, mWindowParams);mDragView = v;}private void stopDragging() {if (mDragView != null) {WindowManager wm = (WindowManager) getContext().getSystemService("window");wm.removeView(mDragView);mDragView.setImageDrawable(null);mDragView = null;}if (mDragBitmap != null) {mDragBitmap.recycle();mDragBitmap = null;}}private void dragView(int x, int y) {float alpha = 1.0f;mWindowParams.alpha = alpha;// }mWindowParams.y = y - mDragPoint + mCoordOffset;mWindowManager.updateViewLayout(mDragView, mWindowParams);}private int getItemForPosition(int y) {int adjustedy = y - mDragPoint - mItemHeightHalf;int pos = myPointToPosition(0, adjustedy);if (pos >= 0) {if (pos <= mFirstDragPos) {pos += 1;}} else if (adjustedy < 0) {pos = 0;}return pos;}private void adjustScrollBounds(int y) {if (y >= mHeight / 3) {mUpperBound = mHeight / 3;}if (y <= mHeight * 2 / 3) {mLowerBound = mHeight * 2 / 3;}}/* * Restore size and visibility for all listitems */private void unExpandViews(boolean deletion) {for (int i = 0;; i++) {View v = getChildAt(i);if (v == null) {if (deletion) {// HACK force update of mItemCountint position = getFirstVisiblePosition();int y = getChildAt(0).getTop();setAdapter(getAdapter());setSelectionFromTop(position, y);// end hack}layoutChildren(); // force children to be recreated where neededv = getChildAt(i);if (v == null) {break;}}ViewGroup.LayoutParams params = v.getLayoutParams();params.height = mItemHeightNormal;v.setLayoutParams(params);v.setVisibility(View.VISIBLE);}}/* * Adjust visibility and size to make it appear as though an item is being * dragged around and other items are making room for it: If dropping the * item would result in it still being in the same place, then make the * dragged listitem's size normal, but make the item invisible. Otherwise, * if the dragged listitem is still on screen, make it as small as possible * and expand the item below the insert point. If the dragged item is not on * screen, only expand the item below the current insertpoint. */private void doExpansion() {int childnum = mDragPos - getFirstVisiblePosition();if (mDragPos > mFirstDragPos) {childnum++;}View first = getChildAt(mFirstDragPos - getFirstVisiblePosition());for (int i = 0;; i++) {View vv = getChildAt(i);if (vv == null) {break;}int height = mItemHeightNormal;int visibility = View.VISIBLE;if (vv.equals(first)) {// processing the item that is being draggedif (mDragPos == mFirstDragPos) {// hovering over the original locationvisibility = View.INVISIBLE;} else {// not hovering over itheight = 1;}} else if (i == childnum) {if (mDragPos < getCount() - 1) {height = mItemHeightExpanded;}}ViewGroup.LayoutParams params = vv.getLayoutParams();params.height = height;vv.setLayoutParams(params);vv.setVisibility(visibility);}}/* * pointToPosition() doesn't consider invisible views, but we need to, so * implement a slightly different version. */private int myPointToPosition(int x, int y) {Rect frame = mTempRect;final int count = getChildCount();for (int i = count - 1; i >= 0; i--) {final View child = getChildAt(i);child.getHitRect(frame);if (frame.contains(x, y)) {return getFirstVisiblePosition() + i;}}return INVALID_POSITION;}public interface DropListener {//void drop(int from, int to);//void onDeleteClicked(int index);}public void setDropListener(DropListener onDrop) {// TODO Auto-generated method stubmDropListener = onDrop;}}


使用:
package com.ql.activity;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.TextView;import com.ql.view.DraggableListView;public class Test_6_Activity  extends Activity{private DraggableListViewmListView;private DraggableArrayAdapter adapter = null;private ArrayList<Map<String, String>> array;//privateintmIndex;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.test5);mListView = (DraggableListView) findViewById(R.id.draggable_list);  array = getData();adapter = new DraggableArrayAdapter();mListView.setAdapter(adapter);mListView.setDropListener(onDrop);//mListView.getAdapter();////列表点击事件处理//        mListView.setOnItemClickListener(new OnItemClickListener() {////        @Override//        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,//        long arg3) {//        //        //Toast.makeText(context, "Click "+arg2, Toast.LENGTH_SHORT).show();//        }//        });   //        //        mListView.setOnItemLongClickListener(new OnItemLongClickListener() {//        //        @Override//        public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int position,//        long id) {//        mIndex = position;//        return false;//        }//        });}//初始化数据private ArrayList<Map<String, String>> getData() {ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();for(int i=0; i<5; i++) {Map<String, String> map = new HashMap<String, String>();map.put("code", "code"+i);map.put("name", "name"+i);list.add(map);}return list;}private DraggableListView.DropListener onDrop = new DraggableListView.DropListener() {@Overridepublic void drop(int from, int to) {Map<String, String> item = adapter.getItem(from);adapter.remove(item);adapter.insert(item, to);}@Overridepublic void onDeleteClicked(int index) {//mIndex = index;delete(index);}};private void delete(final int index) {String prompt = "delete "+array.get(index).get("name").toString()+" "+array.get(index).get("code").toString()+"?";//删除确认对话new AlertDialog.Builder(Test_6_Activity.this).setTitle("删除?")//.setIcon(android.R.drawable.ic_menu_help).setMessage(prompt).setCancelable(true).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Map<String, String> item = adapter.getItem(index);adapter.remove(item);}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();}}).show();}/** * 适配器 * @author admin * */class DraggableArrayAdapter extends ArrayAdapter<Map<String, String>> {DraggableArrayAdapter() {super(Test_6_Activity.this, R.layout.row_simple_list_item_4, array);}public ArrayList<Map<String, String>> getList() {return array;}public View getView(int position, View convertView, ViewGroup parent) {View row = convertView;if (row == null) {LayoutInflater inflater = getLayoutInflater();row = inflater.inflate(R.layout.row_simple_list_item_4, parent, false);}TextView code = (TextView) row.findViewById(R.id.code);code.setText(array.get(position).get("code").toString());TextView name = (TextView) row.findViewById(R.id.name);name.setText(array.get(position).get("name").toString());return (row);}}}


text5.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.ql.view.DraggableListViewandroid:id="@+id/draggable_list"android:layout_width="fill_parent" android:layout_height="fill_parent"/></LinearLayout>

适配器中使用的布局文件row_simple_list_item_4.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"    >    <!--     android:background="@drawable/list_bg"     -->    <ImageView android:id="@+id/iconimg"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:layout_alignParentBottom="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"android:src="@drawable/grabber"/>    <ImageView android:id="@+id/delete"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"    android:paddingRight="5dip"        android:src="@android:drawable/ic_delete"/><TextView android:id="@+id/code"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:paddingLeft="10dip"        android:layout_toRightOf="@id/iconimg"android:layout_centerVertical="true"android:textSize="20dip"android:textColor="#888888"/><TextView android:id="@+id/name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:paddingLeft="10dip"        android:layout_toRightOf="@id/code"android:layout_centerVertical="true"android:textSize="20dip"android:textColor="#888888"/></RelativeLayout>



另一个ListView:
http://blog.csdn.net/sodino/archive/2010/12/15/6077017.aspx
1.实现根据字母进行分类。
2.实现快速滑动。
3.实现快速滑动的提示。
4.实现快捷弹窗。

自定义Android ListView控件:ExpandableListView
http://www.pin5i.com/showtopic-custom-android-listview-control-expandablelistview.html

另一篇关于listview的拖动效果
android listview拖拽,拖动item 改变位置
http://blog.csdn.net/dany1202/archive/2010/12/31/6109160.aspx
在packages/apps/Music/src/touchIncepter.java中
该类提供了listview的拖动效果,并提供接口,在程序接口中实现数据的交换即可。
package com.and.DragListview;  import java.util.ArrayList;  import java.util.List;  import android.app.ListActivity;  import android.content.Context;  import android.os.Bundle;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.BaseAdapter;  import android.widget.ImageView;  import android.widget.TextView;  public class DragListview extends ListActivity {         MyAdapter adapter;      TouchInterceptor list;      List<String> arrayText;            @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);                    list = (TouchInterceptor) getListView();//(TouchInterceptor)findViewById(android.R.id.list);          getText();                    adapter = new MyAdapter(this);          setListAdapter(adapter);                   list.setDropListener(mDropListener);       //   list.setRemoveListener(mRemoveListener);            }      public void getText(){          arrayText = new ArrayList<String>();          arrayText.add("传奇");          arrayText.add("红豆");          arrayText.add("流年");          arrayText.add("棋子");      }            //交换listview的数据      private TouchInterceptor.DropListener mDropListener =          new TouchInterceptor.DropListener() {          public void drop(int from, int to) {              String item = arrayText.get(from);              arrayText.remove(item);//.remove(from);              arrayText.add(to, item);              adapter.notifyDataSetChanged();          }      };            private TouchInterceptor.RemoveListener mRemoveListener =          new TouchInterceptor.RemoveListener() {          public void remove(int which) {                    }      };            class MyAdapter extends BaseAdapter{          private LayoutInflater mInflater;          Context mContext;          public MyAdapter(Context c){              mInflater = LayoutInflater.from(c);          }          public int getCount() {                       return arrayText.size();          }          public Object getItem(int arg0) {              return arrayText.get(arg0);          }          public long getItemId(int arg0) {              return arg0;          }          public View getView(int arg0, View contentView, ViewGroup arg2) {              ImageView img;              TextView text;              if(contentView==null){                  contentView = mInflater.inflate(R.layout.list_layout, null);                   //contentView = mInflater.inflate(R.layout.list_layout,null);              }              img = (ImageView)contentView.findViewById(R.id.img);              img.setBackgroundResource(R.drawable.icon);              text = (TextView)contentView.findViewById(R.id.text);              text.setText(arrayText.get(arg0).toString());                            return contentView;          }                }  }  

/*  * Copyright (C) 2008 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */  package com.and.DragListview;  import android.content.Context;  import android.content.SharedPreferences;  import android.content.res.Resources;  import android.graphics.Bitmap;  import android.graphics.PixelFormat;  import android.graphics.Rect;  import android.util.AttributeSet;  import android.view.GestureDetector;  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.view.GestureDetector.SimpleOnGestureListener;  import android.widget.AdapterView;  import android.widget.ImageView;  import android.widget.ListView;  public class TouchInterceptor extends ListView {            private ImageView mDragView;      private WindowManager mWindowManager;      private WindowManager.LayoutParams mWindowParams;      private int mDragPos;      // which item is being dragged      private int mFirstDragPos; // where was the dragged item originally      private int mDragPoint;    // at what offset inside the item did the user grab it      private int mCoordOffset;  // the difference between screen coordinates and coordinates in this view      private DragListener mDragListener;      private DropListener mDropListener;      private RemoveListener mRemoveListener;      private int mUpperBound;      private int mLowerBound;      private int mHeight;      private GestureDetector mGestureDetector;      private static final int FLING = 0;      private static final int SLIDE = 1;      private int mRemoveMode = -1;      private Rect mTempRect = new Rect();      private Bitmap mDragBitmap;      private final int mTouchSlop;      private int mItemHeightNormal;      private int mItemHeightExpanded;      private int mItemHeightHalf;      public TouchInterceptor(Context context, AttributeSet attrs) {          super(context, attrs);          SharedPreferences pref = context.getSharedPreferences("Music", 3);          mRemoveMode = pref.getInt("deletemode", -1);          mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();          Resources res = getResources();          mItemHeightNormal = 48;//res.getDimensionPixelSize(R.dimen.normal_height);          mItemHeightHalf = mItemHeightNormal / 2;          mItemHeightExpanded = 48;//res.getDimensionPixelSize(R.dimen.expanded_height);      }            @Override      public boolean onInterceptTouchEvent(MotionEvent ev) {          if (mRemoveListener != null && mGestureDetector == null) {              if (mRemoveMode == FLING) {                  mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() {                      @Override                      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,                              float velocityY) {                          if (mDragView != null) {                              if (velocityX > 1000) {                                  Rect r = mTempRect;                                  mDragView.getDrawingRect(r);                                  if ( e2.getX() > r.right * 2 / 3) {                                      // fast fling right with release near the right edge of the screen                                      stopDragging();                                      mRemoveListener.remove(mFirstDragPos);                                      unExpandViews(true);                                  }                              }                              // flinging while dragging should have no effect                              return true;                          }                          return false;                      }                  });              }          }          if (mDragListener != null || mDropListener != null) {              switch (ev.getAction()) {                  case MotionEvent.ACTION_DOWN:                      int x = (int) ev.getX();                      int y = (int) ev.getY();                      int itemnum = pointToPosition(x, y);                      if (itemnum == AdapterView.INVALID_POSITION) {                          break;                      }                      ViewGroup item = (ViewGroup) getChildAt(itemnum - getFirstVisiblePosition());                      mDragPoint = y - item.getTop();                      mCoordOffset = ((int)ev.getRawY()) - y;                      View dragger = item.findViewById(R.id.img);//..........................                      Rect r = mTempRect;                      dragger.getDrawingRect(r);                      // The dragger icon itself is quite small, so pretend the touch area is bigger                      if (x < r.right * 2) {                          item.setDrawingCacheEnabled(true);                          // Create a copy of the drawing cache so that it does not get recycled                          // by the framework when the list tries to clean up memory                          Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());                          startDragging(bitmap, y);                          mDragPos = itemnum;                          mFirstDragPos = mDragPos;                          mHeight = getHeight();                          int touchSlop = mTouchSlop;                          mUpperBound = Math.min(y - touchSlop, mHeight / 3);                          mLowerBound = Math.max(y + touchSlop, mHeight * 2 /3);                          return false;                      }                      stopDragging();                      break;              }          }          return super.onInterceptTouchEvent(ev);      }            /*      * pointToPosition() doesn't consider invisible views, but we      * need to, so implement a slightly different version.      */      private int myPointToPosition(int x, int y) {          if (y < 0) {              // when dragging off the top of the screen, calculate position              // by going back from a visible item              int pos = myPointToPosition(x, y + mItemHeightNormal);              if (pos > 0) {                  return pos - 1;              }          }          Rect frame = mTempRect;          final int count = getChildCount();          for (int i = count - 1; i >= 0; i--) {              final View child = getChildAt(i);              child.getHitRect(frame);              if (frame.contains(x, y)) {                  return getFirstVisiblePosition() + i;              }          }          return INVALID_POSITION;      }            private int getItemForPosition(int y) {          int adjustedy = y - mDragPoint - mItemHeightHalf;          int pos = myPointToPosition(0, adjustedy);          if (pos >= 0) {              if (pos <= mFirstDragPos) {                  pos += 1;              }          } else if (adjustedy < 0) {              // this shouldn't happen anymore now that myPointToPosition deals              // with this situation              pos = 0;          }          return pos;      }            private void adjustScrollBounds(int y) {          if (y >= mHeight / 3) {              mUpperBound = mHeight / 3;          }          if (y <= mHeight * 2 / 3) {              mLowerBound = mHeight * 2 / 3;          }      }      /*      * Restore size and visibility for all listitems      */      private void unExpandViews(boolean deletion) {          for (int i = 0;; i++) {              View v = getChildAt(i);              if (v == null) {                  if (deletion) {                      // HACK force update of mItemCount                      int position = getFirstVisiblePosition();                      int y = getChildAt(0).getTop();                      setAdapter(getAdapter());                      setSelectionFromTop(position, y);                      // end hack                  }                  layoutChildren(); // force children to be recreated where needed                  v = getChildAt(i);                  if (v == null) {                      break;                  }              }              ViewGroup.LayoutParams params = v.getLayoutParams();              params.height = mItemHeightNormal;              v.setLayoutParams(params);              v.setVisibility(View.VISIBLE);          }      }            /* Adjust visibility and size to make it appear as though      * an item is being dragged around and other items are making      * room for it:      * If dropping the item would result in it still being in the      * same place, then make the dragged listitem's size normal,      * but make the item invisible.      * Otherwise, if the dragged listitem is still on screen, make      * it as small as possible and expand the item below the insert      * point.      * If the dragged item is not on screen, only expand the item      * below the current insertpoint.      */      private void doExpansion() {          int childnum = mDragPos - getFirstVisiblePosition();          if (mDragPos > mFirstDragPos) {              childnum++;          }          View first = getChildAt(mFirstDragPos - getFirstVisiblePosition());          for (int i = 0;; i++) {              View vv = getChildAt(i);              if (vv == null) {                  break;              }              int height = mItemHeightNormal;              int visibility = View.VISIBLE;              if (vv.equals(first)) {                  // processing the item that is being dragged                  if (mDragPos == mFirstDragPos) {                      // hovering over the original location                      visibility = View.INVISIBLE;                  } else {                      // not hovering over it                      height = 1;                  }              } else if (i == childnum) {                  if (mDragPos < getCount() - 1) {                      height = mItemHeightExpanded;                  }              }              ViewGroup.LayoutParams params = vv.getLayoutParams();              params.height = height;              vv.setLayoutParams(params);              vv.setVisibility(visibility);          }      }            @Override      public boolean onTouchEvent(MotionEvent ev) {          if (mGestureDetector != null) {              mGestureDetector.onTouchEvent(ev);          }          if ((mDragListener != null || mDropListener != null) && mDragView != null) {              int action = ev.getAction();               switch (action) {                  case MotionEvent.ACTION_UP:                  case MotionEvent.ACTION_CANCEL:                      Rect r = mTempRect;                      mDragView.getDrawingRect(r);                      stopDragging();                      if (mRemoveMode == SLIDE && ev.getX() > r.right * 3 / 4) {                          if (mRemoveListener != null) {                              mRemoveListener.remove(mFirstDragPos);                          }                          unExpandViews(true);                      } else {                          if (mDropListener != null && mDragPos >= 0 && mDragPos < getCount()) {                              mDropListener.drop(mFirstDragPos, mDragPos);                          }                          unExpandViews(false);                      }                      break;                                        case MotionEvent.ACTION_DOWN:                  case MotionEvent.ACTION_MOVE:                      int x = (int) ev.getX();                      int y = (int) ev.getY();                      dragView(x, y);                      int itemnum = getItemForPosition(y);                      if (itemnum >= 0) {                          if (action == MotionEvent.ACTION_DOWN || itemnum != mDragPos) {                              if (mDragListener != null) {                                  mDragListener.drag(mDragPos, itemnum);                              }                              mDragPos = itemnum;                              doExpansion();                          }                          int speed = 0;                          adjustScrollBounds(y);                          if (y > mLowerBound) {                              // scroll the list up a bit                              speed = y > (mHeight + mLowerBound) / 2 ? 16 : 4;                          } else if (y < mUpperBound) {                              // scroll the list down a bit                              speed = y < mUpperBound / 2 ? -16 : -4;                          }                          if (speed != 0) {                              int ref = pointToPosition(0, mHeight / 2);                              if (ref == AdapterView.INVALID_POSITION) {                                  //we hit a divider or an invisible view, check somewhere else                                  ref = pointToPosition(0, mHeight / 2 + getDividerHeight() + 64);                              }                              View v = getChildAt(ref - getFirstVisiblePosition());                              if (v!= null) {                                  int pos = v.getTop();                                  setSelectionFromTop(ref, pos - speed);                              }                          }                      }                      break;              }              return true;          }          return super.onTouchEvent(ev);      }            private void startDragging(Bitmap bm, int y) {          stopDragging();          mWindowParams = new WindowManager.LayoutParams();          mWindowParams.gravity = Gravity.TOP;          mWindowParams.x = 0;          mWindowParams.y = y - mDragPoint + mCoordOffset;          mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;          mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;          mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE                  | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE                  | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON                  | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN                  | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;          mWindowParams.format = PixelFormat.TRANSLUCENT;          mWindowParams.windowAnimations = 0;                    Context context = getContext();          ImageView v = new ImageView(context);  //        int backGroundColor = context.getResources().getColor(R.color.dragndrop_background);  //        v.setBackgroundColor(backGroundColor);          v.setImageBitmap(bm);          mDragBitmap = bm;          mWindowManager = (WindowManager)context.getSystemService("window");          mWindowManager.addView(v, mWindowParams);          mDragView = v;      }            private void dragView(int x, int y) {          if (mRemoveMode == SLIDE) {              float alpha = 1.0f;              int width = mDragView.getWidth();              if (x > width / 2) {                  alpha = ((float)(width - x)) / (width / 2);              }              mWindowParams.alpha = alpha;          }          if (mRemoveMode == FLING) {              mWindowParams.x = x;          }          mWindowParams.y = y - mDragPoint + mCoordOffset;          mWindowManager.updateViewLayout(mDragView, mWindowParams);      }            private void stopDragging() {          if (mDragView != null) {              WindowManager wm = (WindowManager)getContext().getSystemService("window");              wm.removeView(mDragView);              mDragView.setImageDrawable(null);              mDragView = null;          }          if (mDragBitmap != null) {              mDragBitmap.recycle();              mDragBitmap = null;          }      }            public void setDragListener(DragListener l) {          mDragListener = l;      }            public void setDropListener(DropListener l) {          mDropListener = l;      }            public void setRemoveListener(RemoveListener l) {          mRemoveListener = l;      }      public interface DragListener {          void drag(int from, int to);      }      public interface DropListener {          void drop(int from, int to);      }      public interface RemoveListener {          void remove(int which);      }  }  

<com.and.DragListview.TouchInterceptor
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"       
        android:textSize="18sp"
        android:drawSelectorOnTop="false"
        android:fastScrollEnabled="true" />


还有这个:
http://www.eoeandroid.com/thread-61490-1-1.html

Android学习系列(12)--App列表之拖拽GridView
http://www.cnblogs.com/qianxudetianxia/archive/2011/06/20/2084886.html
原创粉丝点击