自定义ListView:

package com.miao.listview;import android.content.Context;import android.content.res.TypedArray;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;import com.miao.listview.R;public class DraggableListView extends ListView {private ImageView mDragView;private WindowManager mWindowManager;private WindowManager.LayoutParams mWindowParams;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 DragListener mDragListener;private DropListener mDropListener;private RemoveListener mRemoveListener;private int mUpperBound;private int mLowerBound;private int mHeight;private GestureDetector mGestureDetector;public static final int FLING = 0;public static final int SLIDE_RIGHT = 1;public static final int SLIDE_LEFT = 2;private int mRemoveMode = -1;private Rect mTempRect = new Rect();private Bitmap mDragBitmap;private final int mTouchSlop;private int mItemHeightNormal = -1;private int mItemHeightExpanded = -1;private int grabberId = -1;private int dragndropBackgroundColor = 0x00000000;public DraggableListView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DraggableListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mTouchSlop = 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 onInterceptTouchEvent(MotionEvent ev) {if (mRemoveListener != null && mGestureDetector == null) {if (mRemoveMode == FLING) {mGestureDetector = new GestureDetector(getContext(),new SimpleOnGestureListener() {@Overridepublic 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 screenstopDragging();mRemoveListener.remove(mFirstDragPos);unExpandViews(true);}}// flinging while dragging should have no// effectreturn 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(grabberId);Rect 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;}mDragView = null;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) {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 - 32;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);}}@Overridepublic 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 (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 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);}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 dragView(int x, int y) {float alpha = 1.0f;int width = mDragView.getWidth();if (mRemoveMode == SLIDE_RIGHT) {if (x > width / 2) {alpha = ((float) (width - x)) / (width / 2);}mWindowParams.alpha = alpha;} else if (mRemoveMode == SLIDE_LEFT) {if (x < width / 2) {alpha = ((float) x) / (width / 2);}mWindowParams.alpha = alpha;}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);}}
调用自定义view:

package com.miao.listview;import android.os.Bundle;import android.app.ListActivity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.TextView;import android.widget.Toast;import com.miao.listview.R;import java.util.ArrayList;import java.util.Arrays;public class DragDemo extends ListActivity {private static String[] items = { "浙江", "江苏", "广东", "上海", "北京", "新疆" };private IconicAdapter adapter = null;private ArrayList<String> array = new ArrayList<String>(Arrays.asList(items));@Overridepublic void onCreate(Bundle icicle) {super.onCreate(icicle);setContentView(R.layout.main);adapter = new IconicAdapter();setListAdapter(adapter);DraggableListView tlv = (DraggableListView) getListView();tlv.setDropListener(onDrop);tlv.setRemoveListener(onRemove);tlv.getAdapter();}private DraggableListView.DropListener onDrop = new DraggableListView.DropListener() {@Overridepublic void drop(int from, int to) {String item = adapter.getItem(from);adapter.remove(item);adapter.insert(item, to);Toast.makeText(DragDemo.this, adapter.getList().toString(),Toast.LENGTH_SHORT).show();}};private DraggableListView.RemoveListener onRemove = new DraggableListView.RemoveListener() {@Overridepublic void remove(int which) {adapter.remove(adapter.getItem(which));}};class IconicAdapter extends ArrayAdapter<String> {IconicAdapter() {super(DragDemo.this, R.layout.row, array);}public ArrayList<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, parent, false);}TextView label = (TextView) row.findViewById(R.id.label);label.setText(array.get(position));return (row);}}}


main.xml:

<?xml version="1.0" encoding="utf-8"?><com.miao.listview.DraggableListViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tlv="http://schemas.android.com/apk/res/com.miao.listview"android:id="@android:id/list"android:layout_width="fill_parent"android:layout_height="fill_parent"android:drawSelectorOnTop="false"tlv:normal_height="64dip"tlv:grabber="@+id/icon"tlv:remove_mode="slideLeft"/>

row.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="64dip"    android:gravity="center_vertical"    android:ignoreGravity="@+id/icon">    <ImageView android:id="@+id/icon"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true"        android:layout_alignParentBottom="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"android:src="@drawable/grabber"/><TextView android:id="@+id/label"        android:textAppearance="?android:attr/textAppearanceMedium"        android:layout_width="wrap_content"        android:paddingLeft="9dip"        android:paddingRight="9dip"        android:layout_height="wrap_content"        android:layout_alignWithParentIfMissing="true"android:layout_alignParentLeft="true"        android:layout_toLeftOf="@id/icon"android:layout_centerVertical="true"        android:ellipsize="marquee"        android:singleLine="true"/></RelativeLayout>

素材图片:



效果图:


更多相关文章

  1. Android之解析Android(安卓)Map地图返回的Json数据
  2. Android(安卓)ListView的子项的随意拖动效果
  3. 代码设置android:icon,android:label
  4. 让图像识别准确率瞬间下降40个点,「江苏卷」版ImageNet你考得过吗
  5. 外企抵制新疆棉 我国纺织企业如何寻求化解之道
  6. 软件的上榜率仅2%?Smartbi登榜2020广东省名优高新技术产品!
  7. Android(安卓)xmlpull 方式解析xml文件
  8. android级联下拉菜单
  9. Android之解析Android Map地图返回的Json数据

随机推荐

  1. Xamarin.Forms Android登录闪图
  2. Android读写文件
  3. SeekBar 和 RatingBar
  4. android--系统路径获取
  5. 自定义组件研究
  6. android grantRuntimePermission 详解
  7. android字体设置
  8. android 设置 永不休眠
  9. Android(安卓)AM命令行启动程序的方法
  10. Android(安卓)自定义Toast