Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android可拖動排序GridView實現

android可拖動排序GridView實現

編輯:關於Android編程

DragGridView繼承自GridView,當長按選中某個item進行拖動,放手更新GridView順序:   1.重寫onTouchEvent響應拖動事件:被按下時記錄按下坐標;拖動時更新被拖動視圖顯示;放開時更新排序   2.設置OnItemLongClickListener:響應長按選取拖動item,獲取被選中item bitmap,添加到窗口顯示   3.通過view.getDrawingCache()獲取被選中item的bitmap,用於繪制拖動的view   4.使用WindowManager來向窗口添加view,更新view顯示。關於WindowManagerService對窗口的組織方式,博客http://blog.csdn.net/luoshengyang/article/details/8498908有介紹,可以參考。   5. MotionEvent中的getX()為相對於容器的坐標,這裡就是GridView;getRawX()為相對於整個屏幕的坐標   DragGridView實現如下,注釋中有更詳細的解釋       1 public class DragGridView extends GridView {   2     private static final int DRAG_IMG_SHOW = 1;   3     private static final int DRAG_IMG_NOT_SHOW = 0;   4     private static final String LOG_TAG = "DragGridView";   5     private static final float AMP_FACTOR = 1.2f;   6    7     /**被拖動的視圖*/   8     private ImageView dragImageView;   9     private WindowManager.LayoutParams dragImageViewParams;  10     private WindowManager windowManager;  11     private boolean isViewOnDrag = false;  12   13     /**前一次拖動的位置*/  14     private int preDraggedOverPositon = AdapterView.INVALID_POSITION;  15     private int downRawX;  16     private int downRawY;  17   18     /**長按選中拖動item*/  19     private OnItemLongClickListener onLongClickListener = new OnItemLongClickListener(){  20   21         @Override  22         //長按item開始拖動  23         public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {  24   25             //記錄長按item位置  26             preDraggedOverPositon = position;  27   28             //獲取被長按item的drawing cache  29             view.destroyDrawingCache();  30             view.setDrawingCacheEnabled(true);  31             //通過被長按item,獲取拖動item的bitmap  32             Bitmap dragBitmap = Bitmap.createBitmap(view.getDrawingCache());  33   34             //設置拖動item的參數  35             dragImageViewParams.gravity = Gravity.TOP | Gravity.LEFT;  36             //設置拖動item為原item 1.2倍  37             dragImageViewParams.width = (int)(AMP_FACTOR*dragBitmap.getWidth());  38             dragImageViewParams.height = (int)(AMP_FACTOR*dragBitmap.getHeight());  39             //設置觸摸點為繪制拖動item的中心  40             dragImageViewParams.x = (downRawX - dragImageViewParams.width/2);  41             dragImageViewParams.y = (downRawY - dragImageViewParams.height/2);  42             dragImageViewParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  43                                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE  44                                         | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  45                                         | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;  46             dragImageViewParams.format = PixelFormat.TRANSLUCENT;  47             dragImageViewParams.windowAnimations = 0;  48   49             //dragImageView為被拖動item的容器,清空上一次的顯示  50             if((int)dragImageView.getTag() == DRAG_IMG_SHOW) {  51                 windowManager.removeView(dragImageView);  52                 dragImageView.setTag(DRAG_IMG_NOT_SHOW);  53             }  54   55             //設置本次被長按的item  56             dragImageView.setImageBitmap(dragBitmap);  57   58             //添加拖動item到屏幕  59             windowManager.addView(dragImageView, dragImageViewParams);  60             dragImageView.setTag(DRAG_IMG_SHOW);  61             isViewOnDrag = true;  62   63             //設置被長按item不顯示  64             ((GridViewAdapter)getAdapter()).hideView(position);  65             return true;  66         }  67     };  68   69     public DragGridView(Context context) {  70         super(context);  71         initView();  72     }  73   74     public DragGridView(Context context, AttributeSet attrs) {  75         super(context, attrs);  76         initView();  77     }  78   79     public DragGridView(Context context, AttributeSet attrs, int defStyleAttr) {  80         super(context, attrs, defStyleAttr);  81         initView();  82     }  83   84     public void initView() {  85         setOnItemLongClickListener(onLongClickListener);  86         //初始化顯示被拖動item的image view  87         dragImageView = new ImageView(getContext());  88         dragImageView.setTag(DRAG_IMG_NOT_SHOW);  89         //初始化用於設置dragImageView的參數對象  90         dragImageViewParams = new WindowManager.LayoutParams();  91         //獲取窗口管理對象,用於後面向窗口中添加dragImageView  92         windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);  93     }  94   95   96     @Override  97     public boolean onTouchEvent(MotionEvent ev) {  98   99         //被按下時記錄按下的坐標 100         if(ev.getAction() == MotionEvent.ACTION_DOWN) { 101             //獲取觸摸點相對於屏幕的坐標 102             downRawX = (int)ev.getRawX(); 103             downRawY = (int)ev.getRawY(); 104         } 105         //dragImageView處於被拖動時,更新dragImageView位置 106         else if((ev.getAction() == MotionEvent.ACTION_MOVE) && (isViewOnDrag == true)) { 107             Log.i(LOG_TAG, "" + ev.getRawX() + " " + ev.getRawY()); 108             //設置觸摸點為dragImageView中心 109             dragImageViewParams.x = (int)(ev.getRawX() - dragImageView.getWidth()/2); 110             dragImageViewParams.y = (int)(ev.getRawY() - dragImageView.getHeight()/2); 111             //更新窗口顯示 112             windowManager.updateViewLayout(dragImageView, dragImageViewParams); 113             //獲取當前觸摸點的item position 114             int currDraggedPosition = pointToPosition((int)ev.getX(), (int)ev.getY()); 115             //如果當前停留位置item不等於上次停留位置的item,交換本次和上次停留的item 116             if((currDraggedPosition != AdapterView.INVALID_POSITION) && (currDraggedPosition != preDraggedOverPositon)) { 117                 ((GridViewAdapter)getAdapter()).swapView(preDraggedOverPositon, currDraggedPosition); 118                 preDraggedOverPositon = currDraggedPosition; 119             } 120         } 121         //釋放dragImageView 122         else if((ev.getAction() == MotionEvent.ACTION_UP) && (isViewOnDrag == true)) { 123             ((GridViewAdapter)getAdapter()).showHideView(); 124             if((int)dragImageView.getTag() == DRAG_IMG_SHOW) { 125                 windowManager.removeView(dragImageView); 126                 dragImageView.setTag(DRAG_IMG_NOT_SHOW); 127             } 128             isViewOnDrag = false; 129         } 130         return super.onTouchEvent(ev); 131     } 132 }       GridViewAdapter繼承自BaseAdapter:   1.提供showHideView、hideView兩個方法用於顯示和隱藏選中Item的Text   2.提供swapView方法用於拖動過程中更新GridView中item顯示      1 public class GridViewAdapter extends BaseAdapter {  2     private Context context;  3     private List<String> strList;  4     private int hidePosition = AdapterView.INVALID_POSITION;  5   6     public GridViewAdapter(Context context, List<String> strList) {  7         this.context = context;  8         this.strList = strList;  9     } 10  11     @Override 12     public int getCount() { 13         return strList.size(); 14     } 15  16     @Override 17     public String getItem(int position) { 18         return strList.get(position); 19     } 20  21     @Override 22     public long getItemId(int position) { 23         return position; 24     } 25  26     @Override 27     public View getView(int position, View convertView, ViewGroup parent) { 28         TextView view; 29         if(convertView == null) { 30             view = new TextView(context); 31         } 32         else { 33             view = (TextView)convertView; 34         } 35  36         //hide時隱藏Text 37         if(position != hidePosition) { 38             view.setText(strList.get(position)); 39         } 40         else { 41             view.setText(""); 42         } 43         view.setId(position); 44  45         return view; 46     } 47  48     public void hideView(int pos) { 49         hidePosition = pos; 50         notifyDataSetChanged(); 51     } 52  53     public void showHideView() { 54         hidePosition = AdapterView.INVALID_POSITION; 55         notifyDataSetChanged(); 56     } 57  58     public void removeView(int pos) { 59         strList.remove(pos); 60         notifyDataSetChanged(); 61     } 62  63     //更新拖動時的gridView 64     public void swapView(int draggedPos, int destPos) { 65         //從前向後拖動,其他item依次前移 66         if(draggedPos < destPos) { 67             strList.add(destPos+1, getItem(draggedPos)); 68             strList.remove(draggedPos); 69         } 70         //從後向前拖動,其他item依次後移 71         else if(draggedPos > destPos) { 72             strList.add(destPos, getItem(draggedPos)); 73             strList.remove(draggedPos+1); 74         } 75         hidePosition = destPos; 76         notifyDataSetChanged(); 77     } 78 }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved