Android 高仿 頻道管理----網易、今日頭條、騰訊視頻 (可以拖動的GridView)附源碼DEMO

原地址:http://blog.csdn.net/vipzjyno1/article/details/25005851

距離上次發佈(android高仿系列)今日頭條 --新聞閱讀器 (二)

相關的內容已經半個月了,最近利用空閒時間,把今日頭條客戶端完善了下。完善的功能一個一個全部實現後,就放整個源碼。開發的進度就是按照一個一個功能的思路走的,所以開發一個小的功能,如果有用,就寫一個專門的博客以便有人用到獨立的功能可以方便使用。

這次實現的功能是很多新聞閱讀器(網易,今日頭條,360新聞等)以及騰訊視頻等裏面都會出現的頻道管理功能。


下面先上這次實現功能的效果圖:(注:這個效果圖沒有拖拽的時候移動動畫,DEMO裏面有,可以下載看看)



一、開發心裏歷程

剛開始接觸這個的時候,不知道要如何實現,去網上翻了一大堆資料,懂了個大概,就是目前可以找到的都是拖拽的時候,不帶移動動畫的,和線上的客戶端交互效果相差甚遠,在反反覆覆的嘗試查看相關東西,大致的做了出來,目前在模擬器上似乎有一點小BUG,真機測試沒有問題,就先放上來,如果發現問題在修改優化。代碼反面,沒有好好的修改調整,可能會有點亂,請見諒哈。


二、開發前的準備

1.瞭解重寫View的相關知識,並且知道GridView的一些內部方法,如:怎麼通過觸摸的座標獲取對應的position等(這裏我採用的是繼承GridView控件)

2.瞭解屏幕觸摸動作傳遞原理    這裏我以前轉載的一篇或許會有幫助:Android事件分發機制完全解析,帶你從源碼的角度徹底理解(全)

3.瞭解位移動畫Animation,本DEMO中主要用到:TranslateAnimation  平移動畫

4.瞭解WindowManager的窗口機制,這裏的item拖拽等都要設計到這個。

5.瞭解SQLiteDatabase 以及SQLiteOpenHelper等數據庫操作相關的類,本DEMO中主要用到數據庫進行存儲頻道信息,如果你要用文檔進行存儲讀取也可以。


三、開發思路

1.  獲取數據庫中頻道的列表,如果爲空,賦予默認列表,並存入數據庫,之後通過對應的適配器賦給對應的GridView


2.  2個GridView--(1.DragGrid   2. OtherGridView)

DragGrid 用於顯示我的頻道,帶有長按拖拽效果

OtherGridView用於顯示更多頻道,不帶推拽效果

注:由於屏幕大小不一定,外層使用ScrollView,所以2者都要重寫計算高度


3.  點擊2個GridView的時候,根據點擊的Item對應的position,獲取position對應的view,進行創建一層移動的動畫層

起始位置:點擊的positiongetLocationInWindow()獲取。終點位置:另一個GridView的最後個ITEM 的position + 1的位置。

並賦予移動動畫,等動畫結束後對2者對應的頻道列表進行數據的remove和add操作。


4.  設置點擊和拖動的限制條件,如  推薦  這個ITEM是不允許用戶操作的。


5.  拖動的DragGrid的操作:

(1)長按獲取長按的ITEM的position  -- dragPosition 以及對應的view ,手指觸摸屏幕的時候,調用onInterceptTouchEvent來獲取MotionEvent.ACTION_DOWN事件,獲取對應的數據。由於這裏是繼承了GridView,所以長按時間可以通過setOnItemLongClickListener監聽來執行,或則你也可以通過計算點擊時間來監聽是否長按。

(2)通過onTouchEvent(MotionEvent ev)來監聽手指的移動和擡起動作。當它移動到 其它的item下面,並且下方的item對應的position  不等於 dragPosition,進行數據交換,並且2者之間的所有item進行移動動畫,動畫結束後,數據更替刷新界面。

(3) 擡起手後,清除掉拖動時候創建的view,讓GridView中的數據顯示。


6.  退出時候,將改變後的頻道列表存入數據庫。


四、流程圖

下面是大體的流程圖:




五、核心代碼

點擊進行添加刪除:
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. /** GRIDVIEW對應的ITEM點擊監聽接口  */  
  2.     @Override  
  3.     public void onItemClick(AdapterView<?> parent, final View view, final int position,long id) {  
  4.         //如果點擊的時候,之前動畫還沒結束,那麼就讓點擊事件無效  
  5.         if(isMove){  
  6.             return;  
  7.         }  
  8.         switch (parent.getId()) {  
  9.         case R.id.userGridView:  
  10.             //position爲 0,1 的不可以進行任何操作  
  11.             if (position != 0 && position != 1) {  
  12.                 final ImageView moveImageView = getView(view);  
  13.                 if (moveImageView != null) {  
  14.                     TextView newTextView = (TextView) view.findViewById(R.id.text_item);  
  15.                     final int[] startLocation = new int[2];  
  16.                     newTextView.getLocationInWindow(startLocation);  
  17.                     final ChannelItem channel = ((DragAdapter) parent.getAdapter()).getItem(position);//獲取點擊的頻道內容  
  18.                     otherAdapter.setVisible(false);  
  19.                     //添加到最後一個  
  20.                     otherAdapter.addItem(channel);  
  21.                     new Handler().postDelayed(new Runnable() {  
  22.                         public void run() {  
  23.                             try {  
  24.                                 int[] endLocation = new int[2];  
  25.                                 //獲取終點的座標  
  26.                                 otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);  
  27.                                 MoveAnim(moveImageView, startLocation , endLocation, channel,userGridView);  
  28.                                 userAdapter.setRemove(position);  
  29.                             } catch (Exception localException) {  
  30.                             }  
  31.                         }  
  32.                     }, 50L);  
  33.                 }  
  34.             }  
  35.             break;  
  36.         case R.id.otherGridView:  
  37.             final ImageView moveImageView = getView(view);  
  38.             if (moveImageView != null){  
  39.                 TextView newTextView = (TextView) view.findViewById(R.id.text_item);  
  40.                 final int[] startLocation = new int[2];  
  41.                 newTextView.getLocationInWindow(startLocation);  
  42.                 final ChannelItem channel = ((OtherAdapter) parent.getAdapter()).getItem(position);  
  43.                 userAdapter.setVisible(false);  
  44.                 //添加到最後一個  
  45.                 userAdapter.addItem(channel);  
  46.                 new Handler().postDelayed(new Runnable() {  
  47.                     public void run() {  
  48.                         try {  
  49.                             int[] endLocation = new int[2];  
  50.                             //獲取終點的座標  
  51.                             userGridView.getChildAt(userGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);  
  52.                             MoveAnim(moveImageView, startLocation , endLocation, channel,otherGridView);  
  53.                             otherAdapter.setRemove(position);  
  54.                         } catch (Exception localException) {  
  55.                         }  
  56.                     }  
  57.                 }, 50L);  
  58.             }  
  59.             break;  
  60.         default:  
  61.             break;  
  62.         }  
  63.     }  


移動動畫:
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:14px;">private void MoveAnim(View moveView, int[] startLocation,int[] endLocation, final ChannelItem moveChannel,  
  2.             final GridView clickGridView) {  
  3.         int[] initLocation = new int[2];  
  4.         //獲取傳遞過來的VIEW的座標  
  5.         moveView.getLocationInWindow(initLocation);  
  6.         //得到要移動的VIEW,並放入對應的容器中  
  7.         final ViewGroup moveViewGroup = getMoveViewGroup();  
  8.         final View mMoveView = getMoveView(moveViewGroup, moveView, initLocation);  
  9.         //創建移動動畫  
  10.         TranslateAnimation moveAnimation = new TranslateAnimation(  
  11.                 startLocation[0], endLocation[0], startLocation[1],  
  12.                 endLocation[1]);  
  13.         moveAnimation.setDuration(300L);//動畫時間  
  14.         //動畫配置  
  15.         AnimationSet moveAnimationSet = new AnimationSet(true);  
  16.         moveAnimationSet.setFillAfter(false);//動畫效果執行完畢後,View對象不保留在終止的位置  
  17.         moveAnimationSet.addAnimation(moveAnimation);  
  18.         mMoveView.startAnimation(moveAnimationSet);  
  19.         moveAnimationSet.setAnimationListener(new AnimationListener() {  
  20.               
  21.             @Override  
  22.             public void onAnimationStart(Animation animation) {  
  23.                 isMove = true;  
  24.             }  
  25.               
  26.             @Override  
  27.             public void onAnimationRepeat(Animation animation) {  
  28.             }  
  29.               
  30.             @Override  
  31.             public void onAnimationEnd(Animation animation) {  
  32.                 moveViewGroup.removeView(mMoveView);  
  33.                 // instanceof 方法判斷2邊實例是不是一樣,判斷點擊的是DragGrid還是OtherGridView  
  34.                 if (clickGridView instanceof DragGrid) {  
  35.                     otherAdapter.setVisible(true);  
  36.                     otherAdapter.notifyDataSetChanged();  
  37.                     userAdapter.remove();  
  38.                 }else{  
  39.                     userAdapter.setVisible(true);  
  40.                     userAdapter.notifyDataSetChanged();  
  41.                     otherAdapter.remove();  
  42.                 }  
  43.                 isMove = false;  
  44.             }  
  45.         });  
  46.     }</span>  

可拖拽的DragGrid代碼: 
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. public class DragGrid extends GridView {  
  2.     /** 點擊時候的X位置 */  
  3.     public int downX;  
  4.     /** 點擊時候的Y位置 */  
  5.     public int downY;  
  6.     /** 點擊時候對應整個界面的X位置 */  
  7.     public int windowX;  
  8.     /** 點擊時候對應整個界面的Y位置 */  
  9.     public int windowY;  
  10.     /** 屏幕上的X */  
  11.     private int win_view_x;  
  12.     /** 屏幕上的Y */  
  13.     private int win_view_y;  
  14.     /** 拖動的裏x的距離 */  
  15.     int dragOffsetX;  
  16.     /** 拖動的裏Y的距離 */  
  17.     int dragOffsetY;  
  18.     /** 長按時候對應postion */  
  19.     public int dragPosition;  
  20.     /** Up後對應的ITEM的Position */  
  21.     private int dropPosition;  
  22.     /** 開始拖動的ITEM的Position */  
  23.     private int startPosition;  
  24.     /** item高 */  
  25.     private int itemHeight;  
  26.     /** item寬 */  
  27.     private int itemWidth;  
  28.     /** 拖動的時候對應ITEM的VIEW */  
  29.     private View dragImageView = null;  
  30.     /** 長按的時候ITEM的VIEW */  
  31.     private ViewGroup dragItemView = null;  
  32.     /** WindowManager管理器 */  
  33.     private WindowManager windowManager = null;  
  34.     /** */  
  35.     private WindowManager.LayoutParams windowParams = null;  
  36.     /** item總量 */  
  37.     private int itemTotalCount;  
  38.     /** 一行的ITEM數量 */  
  39.     private int nColumns = 4;  
  40.     /** 行數 */  
  41.     private int nRows;  
  42.     /** 剩餘部分 */  
  43.     private int Remainder;  
  44.     /** 是否在移動 */  
  45.     private boolean isMoving = false;  
  46.     /** */  
  47.     private int holdPosition;  
  48.     /** 拖動的時候放大的倍數 */  
  49.     private double dragScale = 1.2D;  
  50.     /** 震動器 */  
  51.     private Vibrator mVibrator;  
  52.     /** 每個ITEM之間的水平間距 */  
  53.     private int mHorizontalSpacing = 15;  
  54.     /** 每個ITEM之間的豎直間距 */  
  55.     private int mVerticalSpacing = 15;  
  56.     /* 移動時候最後個動畫的ID */  
  57.     private String LastAnimationID;  
  58.   
  59.     public DragGrid(Context context) {  
  60.         super(context);  
  61.         init(context);  
  62.     }  
  63.   
  64.     public DragGrid(Context context, AttributeSet attrs, int defStyle) {  
  65.         super(context, attrs, defStyle);  
  66.         init(context);  
  67.     }  
  68.   
  69.     public DragGrid(Context context, AttributeSet attrs) {  
  70.         super(context, attrs);  
  71.         init(context);  
  72.     }  
  73.   
  74.     public void init(Context context) {  
  75.         mVibrator = (Vibrator) context  
  76.                 .getSystemService(Context.VIBRATOR_SERVICE);  
  77.         // 將佈局文件中設置的間距dip轉爲px  
  78.         mHorizontalSpacing = DataTools.dip2px(context, mHorizontalSpacing);  
  79.     }  
  80.   
  81.     @Override  
  82.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  83.         // TODO Auto-generated method stub  
  84.         if (ev.getAction() == MotionEvent.ACTION_DOWN) {  
  85.             downX = (int) ev.getX();  
  86.             downY = (int) ev.getY();  
  87.             windowX = (int) ev.getX();  
  88.             windowY = (int) ev.getY();  
  89.             setOnItemClickListener(ev);  
  90.         }  
  91.         return super.onInterceptTouchEvent(ev);  
  92.     }  
  93.   
  94.     @Override  
  95.     public boolean onTouchEvent(MotionEvent ev) {  
  96.         // TODO Auto-generated method stub  
  97.         boolean bool = true;  
  98.         if (dragImageView != null  
  99.                 && dragPosition != AdapterView.INVALID_POSITION) {  
  100.             // 移動時候的對應x,y位置  
  101.             bool = super.onTouchEvent(ev);  
  102.             int x = (int) ev.getX();  
  103.             int y = (int) ev.getY();  
  104.             switch (ev.getAction()) {  
  105.             case MotionEvent.ACTION_DOWN:  
  106.                 downX = (int) ev.getX();  
  107.                 windowX = (int) ev.getX();  
  108.                 downY = (int) ev.getY();  
  109.                 windowY = (int) ev.getY();  
  110.                 break;  
  111.             case MotionEvent.ACTION_MOVE:  
  112.                 onDrag(x, y, (int) ev.getRawX(), (int) ev.getRawY());  
  113.                 if (!isMoving) {  
  114.                     OnMove(x, y);  
  115.                 }  
  116.                 if (pointToPosition(x, y) != AdapterView.INVALID_POSITION) {  
  117.                     break;  
  118.                 }  
  119.                 break;  
  120.             case MotionEvent.ACTION_UP:  
  121.                 stopDrag();  
  122.                 onDrop(x, y);  
  123.                 requestDisallowInterceptTouchEvent(false);  
  124.                 break;  
  125.   
  126.             default:  
  127.                 break;  
  128.             }  
  129.         }  
  130.         return super.onTouchEvent(ev);  
  131.     }  
  132.   
  133.     /** 在拖動的情況 */  
  134.     private void onDrag(int x, int y, int rawx, int rawy) {  
  135.         if (dragImageView != null) {  
  136.             windowParams.alpha = 0.6f;  
  137.             windowParams.x = rawx - win_view_x;  
  138.             windowParams.y = rawy - win_view_y;  
  139.             windowManager.updateViewLayout(dragImageView, windowParams);  
  140.         }  
  141.     }  
  142.   
  143.     /** 在鬆手下放的情況 */  
  144.     private void onDrop(int x, int y) {  
  145.         // 根據拖動到的x,y座標獲取拖動位置下方的ITEM對應的POSTION  
  146.         int tempPostion = pointToPosition(x, y);  
  147.         dropPosition = tempPostion;  
  148.         DragAdapter mDragAdapter = (DragAdapter) getAdapter();  
  149.         // 顯示剛拖動的ITEM  
  150.         mDragAdapter.setShowDropItem(true);  
  151.         // 刷新適配器,讓對應的ITEM顯示  
  152.         mDragAdapter.notifyDataSetChanged();  
  153.     }  
  154.   
  155.     /** 
  156.      * 長按點擊監聽 
  157.      * @param ev 
  158.      */  
  159.     public void setOnItemClickListener(final MotionEvent ev) {  
  160.         setOnItemLongClickListener(new OnItemLongClickListener() {  
  161.   
  162.             @Override  
  163.             public boolean onItemLongClick(AdapterView<?> parent, View view,  
  164.                     int position, long id) {  
  165.                 int x = (int) ev.getX();// 長安事件的X位置  
  166.                 int y = (int) ev.getY();// 長安事件的y位置  
  167.                 startPosition = position;// 第一次點擊的postion  
  168.                 dragPosition = position;  
  169.                 if (startPosition <= 1) {  
  170.                     return false;  
  171.                 }  
  172.                 ViewGroup dragViewGroup = (ViewGroup) getChildAt(dragPosition  
  173.                         - getFirstVisiblePosition());  
  174.                 TextView dragTextView = (TextView) dragViewGroup  
  175.                         .findViewById(R.id.text_item);  
  176.                 dragTextView.setSelected(true);  
  177.                 dragTextView.setEnabled(false);  
  178.                 itemHeight = dragViewGroup.getHeight();  
  179.                 itemWidth = dragViewGroup.getWidth();  
  180.                 itemTotalCount = DragGrid.this.getCount();  
  181.                 int row = itemTotalCount / nColumns;// 算出行數  
  182.                 Remainder = (itemTotalCount % nColumns);// 算出最後一行多餘的數量  
  183.                 if (Remainder != 0) {  
  184.                     nRows = row + 1;  
  185.                 } else {  
  186.                     nRows = row;  
  187.                 }  
  188.                 // 如果特殊的這個不等於拖動的那個,並且不等於-1  
  189.                 if (dragPosition != AdapterView.INVALID_POSITION) {  
  190.                     // 釋放的資源使用的繪圖緩存。如果你調用buildDrawingCache()手動沒有調用setDrawingCacheEnabled(真正的),你應該清理緩存使用這種方法。  
  191.                     win_view_x = windowX - dragViewGroup.getLeft();// VIEW相對自己的X,半斤  
  192.                     win_view_y = windowY - dragViewGroup.getTop();// VIEW相對自己的y,半斤  
  193.                     dragOffsetX = (int) (ev.getRawX() - x);// 手指在屏幕的上X位置-手指在控件中的位置就是距離最左邊的距離  
  194.                     dragOffsetY = (int) (ev.getRawY() - y);// 手指在屏幕的上y位置-手指在控件中的位置就是距離最上邊的距離  
  195.                     dragItemView = dragViewGroup;  
  196.                     dragViewGroup.destroyDrawingCache();  
  197.                     dragViewGroup.setDrawingCacheEnabled(true);  
  198.                     Bitmap dragBitmap = Bitmap.createBitmap(dragViewGroup  
  199.                             .getDrawingCache());  
  200.                     mVibrator.vibrate(50);// 設置震動時間  
  201.                     startDrag(dragBitmap, (int) ev.getRawX(),  
  202.                             (int) ev.getRawY());  
  203.                     hideDropItem();  
  204.                     dragViewGroup.setVisibility(View.INVISIBLE);  
  205.                     isMoving = false;  
  206.                     requestDisallowInterceptTouchEvent(true);  
  207.                     return true;  
  208.                 }  
  209.                 return false;  
  210.             }  
  211.         });  
  212.     }  
  213.   
  214.     public void startDrag(Bitmap dragBitmap, int x, int y) {  
  215.         stopDrag();  
  216.         windowParams = new WindowManager.LayoutParams();// 獲取WINDOW界面的  
  217.         // Gravity.TOP|Gravity.LEFT;這個必須加  
  218.         windowParams.gravity = Gravity.TOP | Gravity.LEFT;  
  219.         // 得到preview左上角相對於屏幕的座標  
  220.         windowParams.x = x - win_view_x;  
  221.         windowParams.y = y - win_view_y;  
  222.         // 設置拖拽item的寬和高  
  223.         windowParams.width = (int) (dragScale * dragBitmap.getWidth());// 放大dragScale倍,可以設置拖動後的倍數  
  224.         windowParams.height = (int) (dragScale * dragBitmap.getHeight());// 放大dragScale倍,可以設置拖動後的倍數  
  225.         this.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  
  226.                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE  
  227.                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  
  228.                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;  
  229.         this.windowParams.format = PixelFormat.TRANSLUCENT;  
  230.         this.windowParams.windowAnimations = 0;  
  231.         ImageView iv = new ImageView(getContext());  
  232.         iv.setImageBitmap(dragBitmap);  
  233.         windowManager = (WindowManager) getContext().getSystemService(  
  234.                 Context.WINDOW_SERVICE);// "window"  
  235.         windowManager.addView(iv, windowParams);  
  236.         dragImageView = iv;  
  237.     }  
  238.   
  239.     /** 停止拖動 ,釋放並初始化 */  
  240.     private void stopDrag() {  
  241.         if (dragImageView != null) {  
  242.             windowManager.removeView(dragImageView);  
  243.             dragImageView = null;  
  244.         }  
  245.     }  
  246.   
  247.     /** 在ScrollView內,所以要進行計算高度 */  
  248.     @Override  
  249.     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  250.         int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
  251.                 MeasureSpec.AT_MOST);  
  252.         super.onMeasure(widthMeasureSpec, expandSpec);  
  253.     }  
  254.   
  255.     /** 隱藏 放下 的ITEM */  
  256.     private void hideDropItem() {  
  257.         ((DragAdapter) getAdapter()).setShowDropItem(false);  
  258.     }  
  259.   
  260.     /** 獲取移動動畫 */  
  261.     public Animation getMoveAnimation(float toXValue, float toYValue) {  
  262.         TranslateAnimation mTranslateAnimation = new TranslateAnimation(  
  263.                 Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,  
  264.                 toXValue, Animation.RELATIVE_TO_SELF, 0.0F,  
  265.                 Animation.RELATIVE_TO_SELF, toYValue);// 當前位置移動到指定位置  
  266.         mTranslateAnimation.setFillAfter(true);// 設置一個動畫效果執行完畢後,View對象保留在終止的位置。  
  267.         mTranslateAnimation.setDuration(300L);  
  268.         return mTranslateAnimation;  
  269.     }  
  270.   
  271.     /** 移動的時候觸發 */  
  272.     public void OnMove(int x, int y) {  
  273.         // 拖動的VIEW下方的POSTION  
  274.         int dPosition = pointToPosition(x, y);  
  275.         // 判斷下方的POSTION是否是最開始2個不能拖動的  
  276.         if (dPosition > 1) {  
  277.             if ((dPosition == -1) || (dPosition == dragPosition)) {  
  278.                 return;  
  279.             }  
  280.             dropPosition = dPosition;  
  281.             if (dragPosition != startPosition) {  
  282.                 dragPosition = startPosition;  
  283.             }  
  284.             int movecount;  
  285.             // 拖動的=開始拖的,並且 拖動的 不等於放下的  
  286.             if ((dragPosition == startPosition)  
  287.                     || (dragPosition != dropPosition)) {  
  288.                 // 移需要移動的動ITEM數量  
  289.                 movecount = dropPosition - dragPosition;  
  290.             } else {  
  291.                 // 移需要移動的動ITEM數量爲0  
  292.                 movecount = 0;  
  293.             }  
  294.             if (movecount == 0) {  
  295.                 return;  
  296.             }  
  297.   
  298.             int movecount_abs = Math.abs(movecount);  
  299.   
  300.             if (dPosition != dragPosition) {  
  301.                 // dragGroup設置爲不可見  
  302.                 ViewGroup dragGroup = (ViewGroup) getChildAt(dragPosition);  
  303.                 dragGroup.setVisibility(View.INVISIBLE);  
  304.                 float to_x = 1;// 當前下方positon  
  305.                 float to_y;// 當前下方右邊positon  
  306.                 // x_vlaue移動的距離百分比(相對於自己長度的百分比)  
  307.                 float x_vlaue = ((float) mHorizontalSpacing / (float) itemWidth) + 1.0f;  
  308.                 // y_vlaue移動的距離百分比(相對於自己寬度的百分比)  
  309.                 float y_vlaue = ((float) mVerticalSpacing / (float) itemHeight) + 1.0f;  
  310.                 Log.d("x_vlaue""x_vlaue = " + x_vlaue);  
  311.                 for (int i = 0; i < movecount_abs; i++) {  
  312.                     to_x = x_vlaue;  
  313.                     to_y = y_vlaue;  
  314.                     // 像左  
  315.                     if (movecount > 0) {  
  316.                         // 判斷是不是同一行的  
  317.                         holdPosition = dragPosition + i + 1;  
  318.                         if (dragPosition / nColumns == holdPosition / nColumns) {  
  319.                             to_x = -x_vlaue;  
  320.                             to_y = 0;  
  321.                         } else if (holdPosition % 4 == 0) {  
  322.                             to_x = 3 * x_vlaue;  
  323.                             to_y = -y_vlaue;  
  324.                         } else {  
  325.                             to_x = -x_vlaue;  
  326.                             to_y = 0;  
  327.                         }  
  328.                     } else {  
  329.                         // 向右,下移到上,右移到左  
  330.                         holdPosition = dragPosition - i - 1;  
  331.                         if (dragPosition / nColumns == holdPosition / nColumns) {  
  332.                             to_x = x_vlaue;  
  333.                             to_y = 0;  
  334.                         } else if ((holdPosition + 1) % 4 == 0) {  
  335.                             to_x = -3 * x_vlaue;  
  336.                             to_y = y_vlaue;  
  337.                         } else {  
  338.                             to_x = x_vlaue;  
  339.                             to_y = 0;  
  340.                         }  
  341.                     }  
  342.                     ViewGroup moveViewGroup = (ViewGroup) getChildAt(holdPosition);  
  343.                     Animation moveAnimation = getMoveAnimation(to_x, to_y);  
  344.                     moveViewGroup.startAnimation(moveAnimation);  
  345.                     // 如果是最後一個移動的,那麼設置他的最後個動畫ID爲LastAnimationID  
  346.                     if (holdPosition == dropPosition) {  
  347.                         LastAnimationID = moveAnimation.toString();  
  348.                     }  
  349.                     moveAnimation.setAnimationListener(new AnimationListener() {  
  350.   
  351.                         @Override  
  352.                         public void onAnimationStart(Animation animation) {  
  353.                             // TODO Auto-generated method stub  
  354.                             isMoving = true;  
  355.                         }  
  356.   
  357.                         @Override  
  358.                         public void onAnimationRepeat(Animation animation) {  
  359.                             // TODO Auto-generated method stub  
  360.   
  361.                         }  
  362.   
  363.                         @Override  
  364.                         public void onAnimationEnd(Animation animation) {  
  365.                             // TODO Auto-generated method stub  
  366.                             // 如果爲最後個動畫結束,那執行下面的方法  
  367.                             if (animation.toString().equalsIgnoreCase(  
  368.                                     LastAnimationID)) {  
  369.                                 DragAdapter mDragAdapter = (DragAdapter) getAdapter();  
  370.                                 mDragAdapter.exchange(startPosition,  
  371.                                         dropPosition);  
  372.                                 startPosition = dropPosition;  
  373.                                 dragPosition = dropPosition;  
  374.                                 isMoving = false;  
  375.                             }  
  376.                         }  
  377.                     });  
  378.                 }  
  379.             }  
  380.         }  
  381.     }  
  382. }  

數據庫SQLHelper文件
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. public class SQLHelper extends SQLiteOpenHelper {  
  2.     public static final String DB_NAME = "database.db";// 數據庫名稱  
  3.     public static final int VERSION = 1;  
  4.       
  5.     public static final String TABLE_CHANNEL = "channel";//數據表   
  6.   
  7.     public static final String ID = "id";//  
  8.     public static final String NAME = "name";  
  9.     public static final String ORDERID = "orderId";  
  10.     public static final String SELECTED = "selected";  
  11.     private Context context;  
  12.     public SQLHelper(Context context) {  
  13.         super(context, DB_NAME, null, VERSION);  
  14.         this.context = context;  
  15.     }  
  16.   
  17.     public Context getContext(){  
  18.         return context;  
  19.     }  
  20.       
  21.     @Override  
  22.     public void onCreate(SQLiteDatabase db) {  
  23.         // TODO 創建數據庫後,對數據庫的操作  
  24.         String sql = "create table if not exists "+TABLE_CHANNEL +  
  25.                 "(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +  
  26.                 ID + " INTEGER , " +  
  27.                 NAME + " TEXT , " +  
  28.                 ORDERID + " INTEGER , " +  
  29.                 SELECTED + " SELECTED)";  
  30.         db.execSQL(sql);  
  31.     }  
  32.   
  33.     @Override  
  34.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  35.         // TODO 更改數據庫版本的操作  
  36.         onCreate(db);  
  37.     }  
  38.   
  39. }  

注:本DEMO中,加入了長按震動,所以在權限裏面記得加上“
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <!-- 在SDCard中創建與刪除文件權限 -->  
  2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />  
  3. <!-- 往SDCard寫入數據權限 -->  
  4. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  5. <!-- 震動權限 -->  
  6. <uses-permission android:name="android.permission.VIBRATE"/>  


六、源碼下載

源碼DEMO下載地址如下:下載地址

發佈了25 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章