拖动后:
- 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 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 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 stub
- 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();
- // }
- }
- @Override
- public 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 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);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // TODO Auto-generated method stub
- if (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);//拖动的ImageView
- 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 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;
- }
- //
- View delView = item.findViewById(R.id.delete);//删除的ImageView
- r.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 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);
- }
- }
- /*
- * 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 stub
- mDropListener = 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 DraggableListView mListView;
- private DraggableArrayAdapter adapter = null;
- private ArrayList<Map<String, String>> array;
- // private int mIndex;
- @Override
- public 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() {
- @Override
- public void drop(int from, int to) {
- Map<String, String> item = adapter.getItem(from);
- adapter.remove(item);
- adapter.insert(item, to);
- }
- @Override
- public 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() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Map<String, String> item = adapter.getItem(index);
- adapter.remove(item);
- }
- })
- .setNegativeButton("取消", new DialogInterface.OnClickListener() {
- @Override
- public 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.DraggableListView
- android: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