`
zhujianjia
  • 浏览: 479344 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多

看图,拖动前: 
 
拖动后: 
 

 

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);  
        }  
    }  
}  

 <?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>  

 <?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

转自:http://gundumw100.iteye.com/blog/919325

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics