请选择 进入手机版 | 继续访问电脑版
查看: 51735|回复: 38

[Android开发资源分享] Android 高仿项目:网易、今日头条、腾讯视频 附源码DEMO

[复制链接]
发表于 2014-8-8 11:31 | 显示全部楼层 |阅读模式
距离上次发布Android高仿系列项目:今日头条—新闻阅读器(2)
; _- y, r0 E  N: x. y+ k相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下。完善的功能一个一个全部实现后,就放整个源码。开发的进度就是按照一个一个功能的思路走的,所以开发一个小的功能,如果有用,就写一个专门的博客以便有人用到独立的功能可以方便使用。
/ N, J6 b8 l1 S7 G% _* m这次实现的功能是很多新闻阅读器(网易,今日头条,360新闻等)以及腾讯视频等里面都会出现的频道管理功能。7 N$ j+ I; d4 J7 f: O- D

, u8 J6 X3 e0 s. a+ k

3 g, y' v: M5 v下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看)
6 Z: j- x" N4 N% C+ t6 z9 U. D( w. z1 n7 J$ j( i
* A- L* ?. V# J3 ], w
1399250647_1821.gif
  P9 @8 f- n& A+ I! |) Z: o一、开发心里历程
6 C5 @# n9 V& ?( ^: f0 v
$ j$ \6 {* I1 @6 N6 W8 k. n刚开始接触这个的时候,不知道要如何实现,去网上翻了一大堆资料,懂了个大概,就是目前可以找到的都是拖拽的时候,不带移动动画的,和线上的客户端交互效果相差甚远,在反反复复的尝试查看相关东西,大致的做了出来,目前在模拟器上似乎有一点小BUG,真机测试没有问题,就先放上来,如果发现问题在修改优化。代码反面,没有好好的修改调整,可能会有点乱,请见谅哈。

( G4 a) e% g$ L  B9 r
% o4 A% {8 t. o2 R- O
8 C# D5 r$ j* @8 V8 B1 C$ U" d
二、开发前的准备
& {! C& R, o3 Q! R  f1 j0 a/ `  f
" M* \& l! g0 o7 [, ]
1.了解重写View的相关知识,并且知道GridView的一些内部方法,如:怎么通过触摸的坐标获取对应的position等(这里我采用的是继承GridView控件)
# A$ A7 J) R+ t* F" F1 m2.了解屏幕触摸动作传递原理    这里我以前转载的一篇或许会有帮助:Android事件分发机制完全解析,带你从源码的角度彻底理解(全)
! l# Q& f) J$ j! s

5 M, m* \1 z0 w2 X- u3.了解位移动画Animation,本DEMO中主要用到:TranslateAnimation  平移动画/ d, ~: k/ o# a1 o$ `& M3 Q
4.了解WindowManager的窗口机制,这里的item拖拽等都要设计到这个。' A5 j. Z2 z0 h; L
5.了解SQLiteDatabase 以及SQLiteOpenHelper等数据库操作相关的类,本DEMO中主要用到数据库进行存储频道信息,如果你要用文档进行存储读取也可以。
1 M4 Y) k7 s* L0 @; F
  `$ ^" d& t6 X- m8 g" g
! k3 t: J9 y  U% U2 n
三、开发思路1.  获取数据库中频道的列表,如果为空,赋予默认列表,并存入数据库,之后通过对应的适配器赋给对应的GridView/ N2 i% s& Y* b# [
" [, _2 f% c& ~. A9 l8 t) |
1 s2 f  w/ @1 q/ m* R
2.  2个GridView--(1.DragGrid   2. OtherGridView)
" L/ h% ~' ?) j4 XDragGrid 用于显示我的频道,带有长按拖拽效果8 [7 k2 D7 g3 \6 J# G' Z! Y# O
OtherGridView用于显示更多频道,不带推拽效果* D+ \5 q$ l$ C, Q
注:由于屏幕大小不一定,外层使用ScrollView,所以2者都要重写计算高度, v* e* }/ I$ v! g4 W$ s/ C. t
. D, M% s! }; c( X$ n
  M' }+ t1 H3 n% {3 }
3.  点击2个GridView的时候,根据点击的Item对应的position,获取position对应的view,进行创建一层移动的动画层3 r3 p& U4 n# d1 b: ?& j5 {9 k( G7 |6 w
起始位置:点击的positiongetLocationInWindow()获取。终点位置:另一个GridView的最后个ITEM 的position + 1的位置。& u* Z4 v* G- d; |' l
并赋予移动动画,等动画结束后对2者对应的频道列表进行数据的remove和add操作。, k5 L) j. C5 M0 |" `

9 P5 k. e* a1 ]5 @* l: G% l

% m6 i7 R- {* \* k' V8 U, D$ {' E# n6 A: z4.  设置点击和拖动的限制条件,如  推荐  这个ITEM是不允许用户操作的。
3 N  f% _( V9 p2 ?/ b3 u
1 v, d% L$ Z5 N/ h

5 N$ @5 I7 r, P* ^/ s9 X5.  拖动的DragGrid的操作:
, q; X4 o5 k& J6 C0 U% f" X" H(1)长按获取长按的ITEM的position  -- dragPosition 以及对应的view ,手指触摸屏幕的时候,调用onInterceptTouchEvent来获取MotionEvent.ACTION_DOWN事件,获取对应的数据。由于这里是继承了GridView,所以长按时间可以通过setOnItemLongClickListener监听来执行,或则你也可以通过计算点击时间来监听是否长按。
$ k( i, m( ^6 W# \(2)通过onTouchEvent(MotionEvent ev)来监听手指的移动和抬起动作。当它移动到 其它的item下面,并且下方的item对应的position  不等于 dragPosition,进行数据交换,并且2者之间的所有item进行移动动画,动画结束后,数据更替刷新界面。6 H. l( ^# J4 V' z0 l$ l
(3) 抬起手后,清除掉拖动时候创建的view,让GridView中的数据显示。! T! {8 D( g0 R: k$ L

* }+ }' b; Y+ C) r% s
  G( j/ d" S: p9 G; k
6.  退出时候,将改变后的频道列表存入数据库。
6 C% H( ^- @7 B! b8 O8 }5 p' x6 ^6 {  f# W) d5 B; l

4 e' H; C: Y6 K4 L$ v* B  a四、流程图下面是大体的流程图:
, S# L9 e: T5 ?& d9 ^ 20140504235519968.jpg 5 j# A/ u7 ?7 @' k6 U
五、核心代码点击进行添加删除:% O; i' ^2 Q% w- F
  1. /** GRIDVIEW对应的ITEM点击监听接口  */
    / w. @) H1 L5 ]
  2.         @Override
    0 E0 E+ U- }! Z0 t% U7 N
  3.         public void onItemClick(AdapterView<?> parent, final View view, final int position,long id) {4 l- o( |5 k' ^5 d: _) F
  4.                 //如果点击的时候,之前动画还没结束,那么就让点击事件无效
    0 u- T2 S: n# m4 `+ H9 l/ \0 Y
  5.                 if(isMove){
    3 I2 j* V5 |2 E" Q. a
  6.                         return;  T# }" e  u' G0 I2 \9 g
  7.                 }
    : a6 r, k/ L6 f3 i' }
  8.                 switch (parent.getId()) {. A, g5 G: J' n; h/ B9 y
  9.                 case R.id.userGridView:
    ' B/ _7 j  G8 @) [/ j+ R
  10.                         //position为 0,1 的不可以进行任何操作( `( Q. z, e: x3 l8 ^- D& Z
  11.                         if (position != 0 && position != 1) {
    . X- c+ w: E+ F. x- k; ^6 B' I
  12.                                 final ImageView moveImageView = getView(view);
    & r6 `' w  M7 M7 v+ T3 j( s
  13.                                 if (moveImageView != null) {
    # V% G  x4 \# `2 n2 k4 \: V
  14.                                         TextView newTextView = (TextView) view.findViewById(R.id.text_item);0 c' g- Z/ y1 d& a5 P8 \
  15.                                         final int[] startLocation = new int[2];
    9 V( @2 J& l4 @. l) T
  16.                                         newTextView.getLocationInWindow(startLocation);
    8 p6 {+ S0 U9 ~. Q. J+ f: A
  17.                                         final ChannelItem channel = ((DragAdapter) parent.getAdapter()).getItem(position);//获取点击的频道内容9 @& E5 w( T, M) B% @; p2 j4 e$ |
  18.                                         otherAdapter.setVisible(false);
    # ?: M% a- |4 T4 m, j
  19.                                         //添加到最后一个* ^  U$ S* `4 z  J8 F
  20.                                         otherAdapter.addItem(channel);
    ! h/ E- D4 P2 e4 Q
  21.                                         new Handler().postDelayed(new Runnable() {
    8 K9 N/ P) w7 I% y, l- D
  22.                                                 public void run() {
    / _' ]0 X5 y  ^2 o) n$ p
  23.                                                         try {# V  f( I2 e% V7 ~3 v
  24.                                                                 int[] endLocation = new int[2];
    ) u4 O; @/ h: c2 o6 E
  25.                                                                 //获取终点的坐标
    4 }; Q0 g4 q" o& x
  26.                                                                 otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
    ; |2 T% y0 R! j' j0 a  v2 t
  27.                                                                 MoveAnim(moveImageView, startLocation , endLocation, channel,userGridView);
    ' U$ b1 J. f3 a+ O0 y, a
  28.                                                                 userAdapter.setRemove(position);" e$ [9 Q8 A; w% e  s9 d
  29.                                                         } catch (Exception localException) {
    : ~) U& ~3 v& h3 J+ l. L
  30.                                                         }
    * K( r9 `. g' n) i  z4 s- G+ s- |6 N# w9 _
  31.                                                 }7 S2 a3 S7 W+ f$ r9 h
  32.                                         }, 50L);) e  m0 k2 y8 E" R7 m
  33.                                 }
    6 S3 b3 {; v+ r5 N9 t- B
  34.                         }& J: `9 w7 p( r
  35.                         break;
      C6 h- l1 J/ n# C. e  W' q
  36.                 case R.id.otherGridView:
    * p. R# H9 K* S! S' ^
  37.                         final ImageView moveImageView = getView(view);
      B* ?5 s$ w3 Y+ P  L: y
  38.                         if (moveImageView != null){
    # O4 x. S2 [# \1 F; r0 F
  39.                                 TextView newTextView = (TextView) view.findViewById(R.id.text_item);
    ) t" C( Q9 q* N2 s6 d: N/ b
  40.                                 final int[] startLocation = new int[2];+ y4 P. z2 h0 f& w- E! i
  41.                                 newTextView.getLocationInWindow(startLocation);, e5 K0 K. p8 W2 y, p, A( _
  42.                                 final ChannelItem channel = ((OtherAdapter) parent.getAdapter()).getItem(position);
    8 J- O/ Q* X% t; J0 E
  43.                                 userAdapter.setVisible(false);
    & B; T3 v5 ]5 @8 U, G
  44.                                 //添加到最后一个
    8 {! O  V$ a0 }
  45.                                 userAdapter.addItem(channel);, R! J  b& J& i  R* L1 C+ x
  46.                                 new Handler().postDelayed(new Runnable() {. k0 ]) U' i7 X# R* l; \
  47.                                         public void run() {
    3 k5 _  l# K$ M7 B, J+ W
  48.                                                 try {
    7 L( n- j* m6 T' Z2 {9 c0 T6 n
  49.                                                         int[] endLocation = new int[2];
    $ x! V6 j( N/ c, [3 X
  50.                                                         //获取终点的坐标
    / f8 W" \0 u* P3 H+ G
  51.                                                         userGridView.getChildAt(userGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);; _+ c0 p, |5 l# ^' N* B& ]2 ?- [
  52.                                                         MoveAnim(moveImageView, startLocation , endLocation, channel,otherGridView);7 i. @# h2 ]1 n0 m8 y/ i( j; y
  53.                                                         otherAdapter.setRemove(position);
    ) {1 P$ \* k% r' J
  54.                                                 } catch (Exception localException) {  w3 E4 T9 f# I; y+ b- P
  55.                                                 }: `# z6 C9 O5 M/ ], n/ e  m
  56.                                         }, J# ?! m& _! i9 u! R
  57.                                 }, 50L);( q( F" e" d! l' V# c, P/ m  x
  58.                         }) O' T  \& z6 r& o
  59.                         break;. n. v' n6 m' N" ?
  60.                 default:; O! j; m: o  E
  61.                         break;
    ! ~; c( A+ ]1 f
  62.                 }
    % F  y+ F% J5 w$ U; N
  63.         }
复制代码
移动动画:( @9 Z1 @, x9 x) |8 a* C, e
  1. <span style="font-size:14px;">private void MoveAnim(View moveView, int[] startLocation,int[] endLocation, final ChannelItem moveChannel,9 h# X  U' p2 o7 R# ~
  2.                         final GridView clickGridView) {. }2 a" i2 o9 M4 Q: J. F6 z) T3 _
  3.                 int[] initLocation = new int[2];
    4 M/ Q' Y5 a% N& _
  4.                 //获取传递过来的VIEW的坐标
    ) `# }  i" X$ S, s( I
  5.                 moveView.getLocationInWindow(initLocation);/ l. W5 d3 G1 A% E! r5 z4 X( q
  6.                 //得到要移动的VIEW,并放入对应的容器中
      ~+ w  G- D, V5 a! i  D) u# U
  7.                 final ViewGroup moveViewGroup = getMoveViewGroup();/ C( X9 _2 X) s
  8.                 final View mMoveView = getMoveView(moveViewGroup, moveView, initLocation);' A# Q4 p9 M$ L- [# {7 {8 Q6 T5 K
  9.                 //创建移动动画
      h( G/ {) F5 o  t0 s: M
  10.                 TranslateAnimation moveAnimation = new TranslateAnimation() s6 s: K( p% |" D0 L! ?2 _
  11.                                 startLocation[0], endLocation[0], startLocation[1],
    : T3 T* r& A5 J' S$ y5 Z3 X0 y( U
  12.                                 endLocation[1]);+ O' |$ x9 y) m6 e. y+ S. R
  13.                 moveAnimation.setDuration(300L);//动画时间
    : t/ M$ z3 n# ^! j% j, G& i
  14.                 //动画配置
    & [4 Z( x( t2 u+ P
  15.                 AnimationSet moveAnimationSet = new AnimationSet(true);; Y5 l" y/ a. L" V6 S
  16.                 moveAnimationSet.setFillAfter(false);//动画效果执行完毕后,View对象不保留在终止的位置
    + \) D1 F( g* C2 }) c2 {& H* a
  17.                 moveAnimationSet.addAnimation(moveAnimation);* \8 e! ?6 _' Y: D
  18.                 mMoveView.startAnimation(moveAnimationSet);
    2 R& U' u2 e' u3 a! m0 a4 R9 r
  19.                 moveAnimationSet.setAnimationListener(new AnimationListener() {7 k) o2 b& b9 b7 @6 L4 d
  20.                         
    # `: f) U( H0 d
  21.                         @Override
    ; K6 P9 M3 Z" i4 `
  22.                         public void onAnimationStart(Animation animation) {
    8 o7 {0 b7 V4 S% a
  23.                                 isMove = true;
    $ R1 ]) z6 F; j4 T) A
  24.                         }4 [4 G7 h, E& x( s8 f+ M% o
  25.                         . a; [" J3 I  T( [
  26.                         @Override
    ) ?8 r) Q. _, {! \5 l
  27.                         public void onAnimationRepeat(Animation animation) {9 m$ P9 Y$ O, V' b! K
  28.                         }/ ^, Y' a2 |* D; a
  29.                         / {& F$ H4 l) i! a& s2 i% I
  30.                         @Override
    5 F6 T) `! y8 E% n5 b  T$ e
  31.                         public void onAnimationEnd(Animation animation) {
    9 |- _$ o2 X- i* \1 d( Z1 a0 B6 T
  32.                                 moveViewGroup.removeView(mMoveView);
    6 k. |* ]1 [' `: v6 ^
  33.                                 // instanceof 方法判断2边实例是不是一样,判断点击的是DragGrid还是OtherGridView% e$ l& u3 s, h- D
  34.                                 if (clickGridView instanceof DragGrid) {2 n" _# d6 d' C) P) u; s
  35.                                         otherAdapter.setVisible(true);$ ?3 ]: F6 T! ?  Z7 V, T
  36.                                         otherAdapter.notifyDataSetChanged();7 c9 f# X- G+ O
  37.                                         userAdapter.remove();
    & }6 u& M! |: {
  38.                                 }else{0 ~* [$ ^. O0 l% h" g
  39.                                         userAdapter.setVisible(true);' G& ]2 O' u* h3 ]5 s  I
  40.                                         userAdapter.notifyDataSetChanged();
    3 G0 Y0 T" `9 r, T8 A' d  M% c
  41.                                         otherAdapter.remove();
    5 B6 P' D! z* S* G, I
  42.                                 }
    5 Y/ l' |  x4 T$ P
  43.                                 isMove = false;" N% o. x" f# h5 o( T/ n0 A( z
  44.                         }
    + M( ]9 D1 }1 q
  45.                 });
    0 g; P' M! ~9 R4 F
  46.         }</span>
复制代码
. @9 Y! @4 ^5 d7 w( B
/ i& P4 E5 Z3 |5 v( M% Q: c/ `5 f, G1 Z. F
+ N% E* q% Q% E! ]) L. k9 n
 楼主| 发表于 2014-8-8 11:34 | 显示全部楼层
可拖拽的DragGrid代码:7 y( l$ ~" x! z8 ?$ h3 V
  1. public class DragGrid extends GridView {0 ]- F7 r; W8 r9 I
  2.         /** 点击时候的X位置 */
    $ R. o6 u  G0 a$ j/ Y
  3.         public int downX;: _; w1 \8 q9 [% n& I0 `& I" r
  4.         /** 点击时候的Y位置 */
    * G1 T) p9 [2 k" S' t9 s
  5.         public int downY;
    , w5 N0 a( g; t. W2 |
  6.         /** 点击时候对应整个界面的X位置 */
    " }- z. m' c4 R5 A9 A$ O
  7.         public int windowX;3 l& I" f8 \! |9 I; f6 q
  8.         /** 点击时候对应整个界面的Y位置 */
    , G6 O: B* g0 R
  9.         public int windowY;
    * ]. V" O% W% U/ i9 o
  10.         /** 屏幕上的X */- v( p8 |# S( v$ |
  11.         private int win_view_x;5 X6 Z7 y: Y+ S7 X
  12.         /** 屏幕上的Y */3 Z0 V/ n& E8 O  X& `) T
  13.         private int win_view_y;' T2 q0 \5 _$ L" P6 u
  14.         /** 拖动的里x的距离 */
    ) l0 ~- _7 N% Y, p: v
  15.         int dragOffsetX;
    # ~6 j! n- {7 N9 D) h2 Y! n. v
  16.         /** 拖动的里Y的距离 */
    + l, h$ {& I, l
  17.         int dragOffsetY;+ M$ s$ ]8 s$ n; W& u% c( q
  18.         /** 长按时候对应postion */
    - A6 ~% e! r4 X  P
  19.         public int dragPosition;( X9 m8 q9 Y5 w! f
  20.         /** Up后对应的ITEM的Position */# |% i5 Q2 Q1 e! Q& w5 a$ _
  21.         private int dropPosition;  F$ r3 G& j, i
  22.         /** 开始拖动的ITEM的Position */
    : p3 b2 ~. C2 j, g% j2 c( Y, z
  23.         private int startPosition;- X0 k6 D  S2 i) G, h. u3 @
  24.         /** item高 */
    5 M& e9 A/ _1 X) J# D
  25.         private int itemHeight;0 U9 u& o* M! N+ g" |- i
  26.         /** item宽 */
    0 f. h3 w2 y, t% v& }9 d
  27.         private int itemWidth;
    6 I+ F+ Z. L$ P7 s: k. w" W5 ]& }+ l8 T$ V
  28.         /** 拖动的时候对应ITEM的VIEW */
      D& _0 l1 m& \4 H% ]
  29.         private View dragImageView = null;- X) V- A3 E' L  I. y) S: x$ p& [' B
  30.         /** 长按的时候ITEM的VIEW */) `8 v; `+ M3 g; W+ N
  31.         private ViewGroup dragItemView = null;, N" p) p4 z5 p; C( Q/ h! h
  32.         /** WindowManager管理器 */
    5 [0 X/ V2 w5 D  G5 O0 j
  33.         private WindowManager windowManager = null;
    5 n5 C% \; o% K) p7 n/ ^6 P
  34.         /** */5 o8 w+ _2 s! [3 n3 k
  35.         private WindowManager.LayoutParams windowParams = null;
    ; B% A+ i- Z. }3 a* p# t
  36.         /** item总量 */( {  Q+ V( m, J  a
  37.         private int itemTotalCount;
    8 _! a. \) [5 O5 o) p$ P6 A
  38.         /** 一行的ITEM数量 */
    ) ^& b1 H* G0 Q4 O
  39.         private int nColumns = 4;
    + D3 p4 d( t% {: M- E% t
  40.         /** 行数 */# B2 W" S+ I* S7 d
  41.         private int nRows;
    + v, j5 Y& f& U2 I3 i
  42.         /** 剩余部分 */. s1 `5 |" }2 ]& ?
  43.         private int Remainder;
    . g6 d9 p2 H' S! {0 g
  44.         /** 是否在移动 */4 V5 E" o5 e/ T7 @- O* @
  45.         private boolean isMoving = false;
    ( _5 N6 C0 c! a3 Z. f
  46.         /** */
    0 r0 n2 y( T/ z" N1 \. ]' m
  47.         private int holdPosition;
    0 e9 T  S# M8 ~( w7 O, `/ h1 r( S
  48.         /** 拖动的时候放大的倍数 */- N8 A# j/ P2 v+ I1 \
  49.         private double dragScale = 1.2D;
    ' y) J4 G' @' {/ l/ J
  50.         /** 震动器 */9 N$ n1 [  w! I2 Z8 i. O7 E
  51.         private Vibrator mVibrator;$ z- K+ l" n2 c5 A3 ?6 S2 ^
  52.         /** 每个ITEM之间的水平间距 */
    1 v5 G. X6 t3 V7 ^$ {
  53.         private int mHorizontalSpacing = 15;
    9 G) q4 n$ u$ K2 W5 T& G
  54.         /** 每个ITEM之间的竖直间距 */
    4 {' l, r9 `5 A" b# \% a& t9 W
  55.         private int mVerticalSpacing = 15;5 g% ]. T; ]4 @+ R, k; f) N
  56.         /* 移动时候最后个动画的ID */* _3 c9 Y! @6 N. A0 y8 N: [
  57.         private String LastAnimationID;
    2 _& x: ?& D$ U- R0 g* h

  58. & I6 V8 }1 E) x0 Q8 s2 y' w
  59.         public DragGrid(Context context) {
    + q2 ~7 G8 H. g1 \5 M
  60.                 super(context);
    4 s( C  y: k6 L6 ~1 D
  61.                 init(context);
    ' E* x- |1 H! i: s( t
  62.         }
    8 a7 M  A, e2 T- l7 V3 Q$ J8 v( P
  63. 7 G) G! `7 E! y. |' o" R
  64.         public DragGrid(Context context, AttributeSet attrs, int defStyle) {, X) ?$ d! h/ W7 \
  65.                 super(context, attrs, defStyle);6 c& q. W1 Q8 C0 w
  66.                 init(context);
    % a' {3 }- A+ H0 |
  67.         }* c$ q$ g; Q+ {7 U' M
  68. % ^, S; ^4 d' [$ p, {4 K
  69.         public DragGrid(Context context, AttributeSet attrs) {
    0 g7 ]1 e! t2 l3 y# L+ C4 O2 o% j; D
  70.                 super(context, attrs);1 h$ j/ ?9 ^; v( F; r% j2 J
  71.                 init(context);0 \8 I' w. P$ b4 p8 _
  72.         }$ k$ s9 p1 S! g8 L

  73. ( L' c; S$ G- a
  74.         public void init(Context context) {
    - z/ _$ A* `9 v! Y0 n
  75.                 mVibrator = (Vibrator) context6 U+ s7 ~5 p  J/ a4 i- N* i
  76.                                 .getSystemService(Context.VIBRATOR_SERVICE);2 D) q( y6 ~# `- ?& F
  77.                 // 将布局文件中设置的间距dip转为px
    3 w: A$ E6 Z# l9 E; e) F
  78.                 mHorizontalSpacing = DataTools.dip2px(context, mHorizontalSpacing);
    - i9 A+ E/ H# O# ^" ]/ \
  79.         }
    " m) v' A* W: z9 l/ _
  80.   E- _) C# n8 z0 |1 z' b
  81.         @Override( Q$ |+ Y8 G2 k) T1 L+ n& n
  82.         public boolean onInterceptTouchEvent(MotionEvent ev) {! ^3 R6 u' [  z, y4 o/ \7 d4 D: s
  83.                 // TODO Auto-generated method stub
    5 g% `2 i& {. O6 A  b) M# j$ h% b
  84.                 if (ev.getAction() == MotionEvent.ACTION_DOWN) {' ]8 x" I/ V/ C' x4 Q$ ^4 w+ X, D
  85.                         downX = (int) ev.getX();
    ( C7 o3 c8 f5 Z- D' v4 _& \
  86.                         downY = (int) ev.getY();
    3 b  i6 |  R/ r5 x  W9 l2 k
  87.                         windowX = (int) ev.getX();
    3 {- u, k4 h1 v
  88.                         windowY = (int) ev.getY();
    / T/ g% @8 I# r0 L5 c7 ?8 I
  89.                         setOnItemClickListener(ev);
    $ h/ i) `( _4 ^$ {! f3 V) C5 ^
  90.                 }3 k2 j0 }. \: U) ?5 t. j
  91.                 return super.onInterceptTouchEvent(ev);3 g! z1 w% c' k6 O6 h# o1 f
  92.         }. d' q+ G: m2 ?3 h( f) q
  93. 4 Q( f  \8 ]+ B7 G
  94.         @Override
    2 X% l2 u+ Z' ^1 R
  95.         public boolean onTouchEvent(MotionEvent ev) {2 V% r/ |  k/ s& d1 m1 _- ?
  96.                 // TODO Auto-generated method stub
    & ?$ Q2 U. U- t" f( u
  97.                 boolean bool = true;
    8 P2 ]8 I1 l$ ?
  98.                 if (dragImageView != null+ s& g9 L. p: ?0 _
  99.                                 && dragPosition != AdapterView.INVALID_POSITION) {% l: D+ K5 X: N  A- O
  100.                         // 移动时候的对应x,y位置
    ( p7 P: b- r* C. T
  101.                         bool = super.onTouchEvent(ev);
    : |; n, \5 }, d2 Y3 {% |
  102.                         int x = (int) ev.getX();; g, R! F" X: R. V* S
  103.                         int y = (int) ev.getY();
    4 w  S3 r% g. a4 n. P
  104.                         switch (ev.getAction()) {
    1 ?/ R0 w) M6 A' b
  105.                         case MotionEvent.ACTION_DOWN:
    9 S5 r" ~0 g& l2 O0 [/ Y
  106.                                 downX = (int) ev.getX();
    ! U8 x2 [' ~7 [' z
  107.                                 windowX = (int) ev.getX();% J. m+ D- s4 f2 E
  108.                                 downY = (int) ev.getY();
    3 `2 h, e: g. T/ ^4 r+ i
  109.                                 windowY = (int) ev.getY();. x) ?  y0 k$ A% H6 q5 [4 y
  110.                                 break;/ _. d. j6 X5 _; p: `9 Q
  111.                         case MotionEvent.ACTION_MOVE:1 Z, t' _, f- U
  112.                                 onDrag(x, y, (int) ev.getRawX(), (int) ev.getRawY());
    ) V7 q1 N1 J) O0 C4 ~. K/ }/ ?2 @! g
  113.                                 if (!isMoving) {, ?0 i2 N2 X  x* V& k
  114.                                         OnMove(x, y);/ ?" k+ w. l/ |( n% k. u3 h
  115.                                 }2 B# I, Y2 E0 z+ W& z% e
  116.                                 if (pointToPosition(x, y) != AdapterView.INVALID_POSITION) {
    9 m9 T0 x6 R  C# m8 E; R+ `
  117.                                         break;
    % H- Z. v- A; X
  118.                                 }
    & L, M" ~% J2 m8 ~
  119.                                 break;/ `2 ^. m: ]5 u/ ^. X
  120.                         case MotionEvent.ACTION_UP:
    + b- t  y: H  |  h: q+ ~! p
  121.                                 stopDrag();$ m* Q! L' s% J2 s9 C
  122.                                 onDrop(x, y);
    5 z: S5 y8 Q" {* @0 B
  123.                                 requestDisallowInterceptTouchEvent(false);
    6 Y+ |: A: Q. Q' U
  124.                                 break;, v2 ], \# J  e- ]7 }! B9 _* }! X
  125. ( l. ]8 m; [' i
  126.                         default:
    2 j8 \, H, T4 U6 L7 ^& h
  127.                                 break;
    5 {% d2 x6 x1 K' D( W8 r! i
  128.                         }
    1 y- c$ k- Q+ q
  129.                 }0 i1 d4 @* o6 B/ `! W
  130.                 return super.onTouchEvent(ev);: Q! v2 M5 {2 j! ]! ]0 V
  131.         }
    9 A: ]1 L$ h0 i) T
  132. 5 J; Y! E( O) d- N
  133.         /** 在拖动的情况 */
      e! d5 Y, X: a0 H; q
  134.         private void onDrag(int x, int y, int rawx, int rawy) {
    " ]. X+ ~5 Y! |* f+ W, V- p; q
  135.                 if (dragImageView != null) {$ i; \& k' t* Y, f. L9 {2 b+ u3 o" a7 M
  136.                         windowParams.alpha = 0.6f;1 `0 H# V3 N0 v% [
  137.                         windowParams.x = rawx - win_view_x;
    # r1 `& Q: z, n' ]1 k
  138.                         windowParams.y = rawy - win_view_y;
    ! M2 f9 s. }! ^1 `) I0 Z
  139.                         windowManager.updateViewLayout(dragImageView, windowParams);! X4 N) S7 @- P% I7 r% {
  140.                 }
    ( i5 Q2 N7 y; y2 [- m3 a
  141.         }- n5 V5 `. ~$ X, K- q: I

  142. # j, P6 y8 |1 x) E; {
  143.         /** 在松手下放的情况 */
    ' |6 t, @3 Z  C
  144.         private void onDrop(int x, int y) {7 @1 [! Z# d: K" M4 r8 F! Z
  145.                 // 根据拖动到的x,y坐标获取拖动位置下方的ITEM对应的POSTION1 Q! t9 y( I# V
  146.                 int tempPostion = pointToPosition(x, y);; L( H. T% t9 o$ B, ?5 p
  147.                 dropPosition = tempPostion;; f! A, I0 C" I4 q* I* t) I
  148.                 DragAdapter mDragAdapter = (DragAdapter) getAdapter();: \; C( \: z* ?0 [2 W2 n9 i
  149.                 // 显示刚拖动的ITEM5 n$ Z: i2 A( m8 m$ g1 Q' V! S3 J
  150.                 mDragAdapter.setShowDropItem(true);' x# T7 i& h* Q! t
  151.                 // 刷新适配器,让对应的ITEM显示
    9 t% B6 w/ y) @! a" `, j" w( q
  152.                 mDragAdapter.notifyDataSetChanged();8 Q  `# D2 t4 D! \  m3 r
  153.         }
    9 K' M: i5 `: X- M7 S. w4 z4 [
  154. + [1 w( P. `3 ^, ]. p+ w5 S
  155.         /**$ Q8 O" [. h6 L; k6 @: v7 A1 Q
  156.          * 长按点击监听
    : a, I7 C! i+ q6 G! y
  157.          * @param ev
    9 N+ q% p5 G3 ]
  158.          *// y1 i/ N# e( N. m9 X! R2 q  c
  159.         public void setOnItemClickListener(final MotionEvent ev) {
    + L9 [: O# k: X+ f& n% l
  160.                 setOnItemLongClickListener(new OnItemLongClickListener() {4 w6 ~# k% K, G! P# p
  161.   [) m5 s; m5 w) Q
  162.                         @Override  h3 R/ f2 z% \# J$ x
  163.                         public boolean onItemLongClick(AdapterView<?> parent, View view,; s" X4 j& e; k' L8 Z
  164.                                         int position, long id) {# l" b- B( |0 T3 H4 l/ }
  165.                                 int x = (int) ev.getX();// 长安事件的X位置1 Z1 i$ f$ u4 H9 K$ a4 _
  166.                                 int y = (int) ev.getY();// 长安事件的y位置! c5 n6 j) f* G4 Y+ n5 o$ V
  167.                                 startPosition = position;// 第一次点击的postion
    / q; J% Q; n2 z; a. B: }
  168.                                 dragPosition = position;3 B' b, p$ S) Y+ X
  169.                                 if (startPosition <= 1) {! H/ d0 C; ~& v
  170.                                         return false;) C! w; _6 g, d% Q- l8 d- e
  171.                                 }
    5 ^4 _" X0 H/ ^2 V$ |& t2 T
  172.                                 ViewGroup dragViewGroup = (ViewGroup) getChildAt(dragPosition
    9 ~! V; @5 u5 u
  173.                                                 - getFirstVisiblePosition());
    ' t3 {7 I4 z3 J2 v3 d# u1 u" i5 B
  174.                                 TextView dragTextView = (TextView) dragViewGroup0 {! ?4 J( t- X  O; n. f6 K! _. \
  175.                                                 .findViewById(R.id.text_item);  i# i/ s- D, _# w$ x, |
  176.                                 dragTextView.setSelected(true);  B+ [, e/ d6 v, r
  177.                                 dragTextView.setEnabled(false);
    6 t1 `5 n8 f4 D% R6 p
  178.                                 itemHeight = dragViewGroup.getHeight();# ^  [: z/ R! f$ y
  179.                                 itemWidth = dragViewGroup.getWidth();
      G# J* m! T! t6 l3 p/ w
  180.                                 itemTotalCount = DragGrid.this.getCount();
    4 J( j/ i* _2 X' {% R* N$ s
  181.                                 int row = itemTotalCount / nColumns;// 算出行数/ K4 D' b! ~+ `1 A! P7 o, t
  182.                                 Remainder = (itemTotalCount % nColumns);// 算出最后一行多余的数量' c6 C: ?1 |" x
  183.                                 if (Remainder != 0) {
    9 |% A  I4 Q! ]- v( M
  184.                                         nRows = row + 1;
    ! E" e6 X5 U: W, b- W% M6 q
  185.                                 } else {1 J* K  w% m$ B& r2 P4 |5 ?$ C/ m
  186.                                         nRows = row;
    % z9 X7 d& n, w9 m5 L
  187.                                 }( t+ A( C9 \. T$ m: i- R
  188.                                 // 如果特殊的这个不等于拖动的那个,并且不等于-1
    & K6 T. h- O! ?  ]( U
  189.                                 if (dragPosition != AdapterView.INVALID_POSITION) {
    & w6 n* p! y7 n$ n7 ]. y
  190.                                         // 释放的资源使用的绘图缓存。如果你调用buildDrawingCache()手动没有调用setDrawingCacheEnabled(真正的),你应该清理缓存使用这种方法。* b4 O! {( w) @( `& U8 I
  191.                                         win_view_x = windowX - dragViewGroup.getLeft();// VIEW相对自己的X,半斤
    ; p8 k$ ]0 Q. f  B- Z
  192.                                         win_view_y = windowY - dragViewGroup.getTop();// VIEW相对自己的y,半斤
    $ |0 Y' j& l! Y* k5 p
  193.                                         dragOffsetX = (int) (ev.getRawX() - x);// 手指在屏幕的上X位置-手指在控件中的位置就是距离最左边的距离
    2 E$ b  Y" _# V- }9 L7 G6 ?- ]
  194.                                         dragOffsetY = (int) (ev.getRawY() - y);// 手指在屏幕的上y位置-手指在控件中的位置就是距离最上边的距离' u& X: n( E- `2 t) r
  195.                                         dragItemView = dragViewGroup;
    7 I7 g. @; a+ V8 B" x! N
  196.                                         dragViewGroup.destroyDrawingCache();
    - j" G0 @6 v; Q. V# o0 L6 l: {
  197.                                         dragViewGroup.setDrawingCacheEnabled(true);6 s2 k8 G4 m" r
  198.                                         Bitmap dragBitmap = Bitmap.createBitmap(dragViewGroup9 e, @8 l2 K/ ~* ~9 u
  199.                                                         .getDrawingCache());
    6 J# j2 E, i# j
  200.                                         mVibrator.vibrate(50);// 设置震动时间4 t, Q; \' l# g8 q" @8 Y
  201.                                         startDrag(dragBitmap, (int) ev.getRawX(),
    : g% @& Z7 G+ Q" @
  202.                                                         (int) ev.getRawY());
    ) V+ Q$ K7 U# W0 X
  203.                                         hideDropItem();0 [/ N9 x) z; u9 F/ T# w
  204.                                         dragViewGroup.setVisibility(View.INVISIBLE);% h1 n$ c5 o4 r& r
  205.                                         isMoving = false;
    4 m' A1 i3 d& Y) M5 h" w" C
  206.                                         requestDisallowInterceptTouchEvent(true);
    2 P7 S4 i" S9 c6 D3 P
  207.                                         return true;
    " s7 ?2 e6 M# Q# Q
  208.                                 }
    # }5 M- X; [0 E5 e+ Q
  209.                                 return false;
    ' X. t/ x6 h0 L+ ~
  210.                         }8 P( o3 h, f4 O, y3 c
  211.                 });
    ' n* T/ [( F- R! d0 v6 ~
  212.         }. K& `. k' e. H

  213. 5 `) V& s% ?" ~9 o( u
  214.         public void startDrag(Bitmap dragBitmap, int x, int y) {
    $ J1 _* ~5 `9 _  H& I
  215.                 stopDrag();/ e, y  ?8 L4 F9 [! E! {8 H0 A0 m
  216.                 windowParams = new WindowManager.LayoutParams();// 获取WINDOW界面的
    8 W7 K; ^7 h3 n$ o. X' c/ S* b
  217.                 // Gravity.TOP|Gravity.LEFT;这个必须加! k' X" m- k2 M7 c- O/ C
  218.                 windowParams.gravity = Gravity.TOP | Gravity.LEFT;! B# l8 ?  Y# ^
  219.                 // 得到preview左上角相对于屏幕的坐标
    : e7 G# |2 L) Q4 t/ j4 u* \
  220.                 windowParams.x = x - win_view_x;
    : o/ V9 R% y  f: n7 J, `6 U& {
  221.                 windowParams.y = y - win_view_y;
    1 X! T: @$ L8 \5 ]0 Y/ J) w2 K
  222.                 // 设置拖拽item的宽和高
    + J5 [9 Q2 ~$ t' |4 y
  223.                 windowParams.width = (int) (dragScale * dragBitmap.getWidth());// 放大dragScale倍,可以设置拖动后的倍数
    * T- N: u0 Y( a, e! r- |$ C: n
  224.                 windowParams.height = (int) (dragScale * dragBitmap.getHeight());// 放大dragScale倍,可以设置拖动后的倍数! Z  V) }* A  W7 L" c: Z( C8 V
  225.                 this.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    + b* V' y- o2 j1 ~- w8 h
  226.                                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
    " [) H3 ]" B$ l$ L  P; C9 S
  227.                                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
      N( R7 ~6 P. h9 b5 R! ~9 J7 N
  228.                                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;5 A2 {5 |* o+ t+ ^" E3 k! j: N+ P
  229.                 this.windowParams.format = PixelFormat.TRANSLUCENT;
    2 O- R8 d' b7 W5 q
  230.                 this.windowParams.windowAnimations = 0;! s" O9 Y4 u5 S
  231.                 ImageView iv = new ImageView(getContext());- Y7 D3 L. S8 t3 O: ?. b% W) k: \
  232.                 iv.setImageBitmap(dragBitmap);
    3 ^+ r2 g9 a& ]/ q3 t3 B; b
  233.                 windowManager = (WindowManager) getContext().getSystemService(1 T+ w: _5 N! ?+ {; y& V
  234.                                 Context.WINDOW_SERVICE);// "window"0 j% `6 l2 |6 z" U/ o3 e" }
  235.                 windowManager.addView(iv, windowParams);
    0 e  s1 {2 k" U& B! ~- p
  236.                 dragImageView = iv;! k0 d- J( e! w- h$ V
  237.         }* q, |5 g6 z' j6 [

  238. & h7 m$ Y0 {" \: u
  239.         /** 停止拖动 ,释放并初始化 */
      u1 z8 J" o! q0 b
  240.         private void stopDrag() {
    1 ]3 s% X5 t3 N- ~- C# Z$ G  Q
  241.                 if (dragImageView != null) {
    8 {% F1 \+ Q3 Z' [" x4 B
  242.                         windowManager.removeView(dragImageView);
    & L" z: {2 }; Q; |
  243.                         dragImageView = null;
    ; q2 t# M, h; w! \$ T0 U1 H" f
  244.                 }
    9 ~. C" l. c* M6 l: t) ?1 u, E5 A
  245.         }
    % Y& p5 ?" Y$ _' n, i

  246. / _: m7 L8 I5 A7 d
  247.         /** 在ScrollView内,所以要进行计算高度 */, a5 O; q' v8 V3 O; m/ e
  248.         @Override- `/ `! n( @9 m; v! Y  G8 v
  249.         public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {+ R: r& w7 T8 i+ }2 ]/ F( l
  250.                 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
    ) X& {- r4 f5 f6 P( K* Y4 ~
  251.                                 MeasureSpec.AT_MOST);  ]% S! S/ z4 w1 w0 c9 G$ ]
  252.                 super.onMeasure(widthMeasureSpec, expandSpec);
    " u3 H& Y0 e3 c" }
  253.         }
    . E2 g) Q. t. R6 x* E
  254. ) D8 B1 |' Q4 j4 s( \+ ?
  255.         /** 隐藏 放下 的ITEM */
    " c% E& }, d/ m3 U. w* o
  256.         private void hideDropItem() {
      k6 Q4 h+ g- ^8 Q8 _
  257.                 ((DragAdapter) getAdapter()).setShowDropItem(false);) M$ F% k4 O% M: x3 D  v
  258.         }1 |+ o7 G1 w5 V, @( |
  259. ' x$ [0 ~9 R0 O- |% \
  260.         /** 获取移动动画 */7 v) y$ O& _; w; }3 m$ _
  261.         public Animation getMoveAnimation(float toXValue, float toYValue) {
    . i# u+ n6 v: {+ _0 S
  262.                 TranslateAnimation mTranslateAnimation = new TranslateAnimation(: N, |9 \2 `( w' ]4 t
  263.                                 Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,2 Q5 H7 R0 u8 p! K" P4 Z8 y
  264.                                 toXValue, Animation.RELATIVE_TO_SELF, 0.0F,
    # j8 A( C/ s: \& @- C! O3 o
  265.                                 Animation.RELATIVE_TO_SELF, toYValue);// 当前位置移动到指定位置
    ! Q! Y% P+ m, u( {% |
  266.                 mTranslateAnimation.setFillAfter(true);// 设置一个动画效果执行完毕后,View对象保留在终止的位置。
    . ~* ?. B# I) V6 f+ _$ V- G
  267.                 mTranslateAnimation.setDuration(300L);4 p7 R6 |' Z- q4 n* r( K7 U
  268.                 return mTranslateAnimation;+ a. v4 i2 {; e5 @
  269.         }
    , `: Y7 s/ B: W( F" c* w; {4 [

  270. - P$ p7 i$ F4 Q! Y& ^
  271.         /** 移动的时候触发 */. S$ W" j7 Z6 m5 t/ z
  272.         public void OnMove(int x, int y) {2 n! @* F% s! f2 V6 h
  273.                 // 拖动的VIEW下方的POSTION
    $ t- Z' {& [" d( b: T
  274.                 int dPosition = pointToPosition(x, y);& c3 r( L$ R7 w; V. h  i4 a- F
  275.                 // 判断下方的POSTION是否是最开始2个不能拖动的
    / |7 T6 I* \& y) z2 Q4 x
  276.                 if (dPosition > 1) {( ~( M8 Q- L  G# Z
  277.                         if ((dPosition == -1) || (dPosition == dragPosition)) {9 A% `: j% X6 `
  278.                                 return;; N' ]2 o; d8 I7 X) }( N/ N% j5 S
  279.                         }) h+ @3 \6 z% l$ Q( i8 D
  280.                         dropPosition = dPosition;
    & U' i" H, ?4 ]- J) x2 U% s# I
  281.                         if (dragPosition != startPosition) {; Y, f4 g9 m0 x
  282.                                 dragPosition = startPosition;
    * E  F1 M6 y, Y6 f
  283.                         }/ I2 }) v( q4 l) J
  284.                         int movecount;
    5 R( ?/ Z, F0 |5 _3 i( O. @( [
  285.                         // 拖动的=开始拖的,并且 拖动的 不等于放下的& M- @' z: L" A) w2 C; `, Z
  286.                         if ((dragPosition == startPosition)- E' L% |* ]' I( q+ G" x) ]6 r
  287.                                         || (dragPosition != dropPosition)) {
    : j+ y; n9 l. r5 @& E+ w3 G
  288.                                 // 移需要移动的动ITEM数量
    % J+ g! `$ u! H* s1 ]
  289.                                 movecount = dropPosition - dragPosition;
      @% y' p) J, o# J& T2 S
  290.                         } else {
    , E3 F0 ~$ \; B5 f
  291.                                 // 移需要移动的动ITEM数量为0" K. |5 i% Y' S1 e% V1 s. F
  292.                                 movecount = 0;$ _4 t8 x/ g+ Y5 N
  293.                         }, A4 N5 H4 `' Y
  294.                         if (movecount == 0) {
    1 m5 h1 @; A  K5 ?
  295.                                 return;  x, M# ~8 F* Z
  296.                         }0 z. X" d7 @, h: O) f7 O  v
  297. ( W; @( e+ Q' E! c, F
  298.                         int movecount_abs = Math.abs(movecount);
    3 }* ~8 f  q5 _$ }* ^+ a3 k

  299. - F! |8 j( S4 v$ X% r
  300.                         if (dPosition != dragPosition) {
    # N  j% d" ^3 V: L5 C  ~
  301.                                 // dragGroup设置为不可见
    6 A1 @/ D  X9 K$ l; s
  302.                                 ViewGroup dragGroup = (ViewGroup) getChildAt(dragPosition);+ p" B+ U& }: r3 ^2 d7 m
  303.                                 dragGroup.setVisibility(View.INVISIBLE);7 J9 I9 w. g- w5 B  d8 T6 I
  304.                                 float to_x = 1;// 当前下方positon3 W- s4 R0 ]; B* T/ ^
  305.                                 float to_y;// 当前下方右边positon
    6 w# \% J, f, U0 D4 `
  306.                                 // x_vlaue移动的距离百分比(相对于自己长度的百分比)
    : R, p+ I6 i) t
  307.                                 float x_vlaue = ((float) mHorizontalSpacing / (float) itemWidth) + 1.0f;2 w5 L+ Z/ p# s' R, l) G
  308.                                 // y_vlaue移动的距离百分比(相对于自己宽度的百分比)) ~7 K7 j2 Y9 X, z7 {+ k9 h
  309.                                 float y_vlaue = ((float) mVerticalSpacing / (float) itemHeight) + 1.0f;
    4 Z' r: n  z7 v
  310.                                 Log.d("x_vlaue", "x_vlaue = " + x_vlaue);
    " q, p  ?* H8 j7 u9 X
  311.                                 for (int i = 0; i < movecount_abs; i++) {
    6 [3 y2 o2 V& x1 K- b; p
  312.                                         to_x = x_vlaue;1 A/ w& T! v  H' J5 r0 L
  313.                                         to_y = y_vlaue;, H  z# I$ ]1 a6 Y. d  \0 d
  314.                                         // 像左  A7 q% D! V3 l2 S" u
  315.                                         if (movecount > 0) {8 v  W* w1 U. w: v
  316.                                                 // 判断是不是同一行的
    5 J4 C3 k2 ]8 L' z7 l
  317.                                                 holdPosition = dragPosition + i + 1;
    + R0 C7 g9 Q; S$ `
  318.                                                 if (dragPosition / nColumns == holdPosition / nColumns) {
    3 {0 E1 `% i4 X
  319.                                                         to_x = -x_vlaue;6 S: ?% s% r' s2 V8 L
  320.                                                         to_y = 0;
    * R+ L7 m. B; a2 _& c8 F6 o3 D$ y
  321.                                                 } else if (holdPosition % 4 == 0) {
    + S. M* [1 q3 {6 O7 e
  322.                                                         to_x = 3 * x_vlaue;- m! U# t# Z. V4 a: e
  323.                                                         to_y = -y_vlaue;
    7 f4 q1 D0 \8 d3 }, Z/ C( w
  324.                                                 } else {, R3 H- V! K" n* y$ V, z
  325.                                                         to_x = -x_vlaue;
    / x( M' R& D/ ^7 \, b' f
  326.                                                         to_y = 0;
    3 J( v+ Q0 b) v! m7 R
  327.                                                 }) X0 \- R  M/ y- A1 l& Q
  328.                                         } else {
    6 G' ]% N5 Q7 ]' V
  329.                                                 // 向右,下移到上,右移到左4 U$ G' e7 Z9 Z! h
  330.                                                 holdPosition = dragPosition - i - 1;, t- T0 i9 A7 _. }" C
  331.                                                 if (dragPosition / nColumns == holdPosition / nColumns) {
    # y0 B) j$ A8 T
  332.                                                         to_x = x_vlaue;9 y5 `+ V3 K+ o5 t% H; ?, Y) s
  333.                                                         to_y = 0;
    . B$ z6 J  H% b1 Y6 d. D
  334.                                                 } else if ((holdPosition + 1) % 4 == 0) {
    $ U, E* n, ?& {4 r4 N& a/ S
  335.                                                         to_x = -3 * x_vlaue;
    # Z/ V" \7 O/ n
  336.                                                         to_y = y_vlaue;* k! I, ?4 V! [5 H. I
  337.                                                 } else {: b. x# p% r+ `
  338.                                                         to_x = x_vlaue;
    8 P% a9 h; x/ T6 ~1 u* f# X
  339.                                                         to_y = 0;2 @% P/ Y( ~: D/ q& L
  340.                                                 }4 y- A; R& ?0 V9 I! \! ^) C* X
  341.                                         }
    ; y/ D6 Z$ d$ T" n8 R  g4 R% e- D
  342.                                         ViewGroup moveViewGroup = (ViewGroup) getChildAt(holdPosition);
    8 F7 T3 S; o" V; k3 H& D
  343.                                         Animation moveAnimation = getMoveAnimation(to_x, to_y);
    1 K; e4 N; P" W  u
  344.                                         moveViewGroup.startAnimation(moveAnimation);
    0 G* r5 O& z2 I1 @( N  m, y- z
  345.                                         // 如果是最后一个移动的,那么设置他的最后个动画ID为LastAnimationID( b( J6 Q  T0 J+ q( T: q. U6 r
  346.                                         if (holdPosition == dropPosition) {
    3 U  A" M# t* Q5 r" |: a
  347.                                                 LastAnimationID = moveAnimation.toString();
    ; O( b7 m0 j  Q. m3 r7 R5 ]! s
  348.                                         }
    ; R9 C  g1 C5 r$ `0 M; v8 U( h" C, Z
  349.                                         moveAnimation.setAnimationListener(new AnimationListener() {& t- ^, x- f; c, |
  350. % j  v' M& ^  ?1 f/ _8 r4 a
  351.                                                 @Override/ f, d) p  B' C$ ~, U& D$ i8 c
  352.                                                 public void onAnimationStart(Animation animation) {
    0 u0 o  {. q. L8 t* b+ [" W) d
  353.                                                         // TODO Auto-generated method stub" y6 t6 R2 l4 @9 _' f
  354.                                                         isMoving = true;
    & C# h3 y& W) v9 o7 s
  355.                                                 }- O: p$ h! Q6 h

  356. 7 v2 D1 s0 n" _- l6 ?
  357.                                                 @Override
    & t: h& Y' A5 Y8 Q8 f
  358.                                                 public void onAnimationRepeat(Animation animation) {) U) F( J& n/ A5 }
  359.                                                         // TODO Auto-generated method stub
    ) x6 A5 N" V; O" i) ^, \

  360. . f7 q9 V5 {5 k  b) k
  361.                                                 }
    9 m, _$ ^# H. B0 e( ^' Y% V

  362. 2 ?6 p. E; Y( }
  363.                                                 @Override
    , F; s8 C6 L7 [* D# W4 D( ?+ p, M
  364.                                                 public void onAnimationEnd(Animation animation) {, F; G5 e- S+ F  e1 h* k! p
  365.                                                         // TODO Auto-generated method stub
    ) v4 c& _* o( w& a; ?# Y$ T
  366.                                                         // 如果为最后个动画结束,那执行下面的方法
    ! _8 Z% `+ T2 y% w2 L3 R- d/ ^# U
  367.                                                         if (animation.toString().equalsIgnoreCase(
    ' }/ d2 r; q5 ~* m
  368.                                                                         LastAnimationID)) {, K1 r9 @4 ?; D+ j. e% n- Y
  369.                                                                 DragAdapter mDragAdapter = (DragAdapter) getAdapter();: e% X  S0 y. g* n$ s0 w
  370.                                                                 mDragAdapter.exchange(startPosition,
    % P. W4 w: e; }( B& {
  371.                                                                                 dropPosition);
    ! [/ }/ G. Z" x; [. e
  372.                                                                 startPosition = dropPosition;
    & @" w; z6 j# w
  373.                                                                 dragPosition = dropPosition;. _3 K4 x- N/ f8 Z( P- `" x
  374.                                                                 isMoving = false;1 g1 E% W7 f  X* s% J3 O8 E
  375.                                                         }: B) x. P  m, }: h% A% m, `
  376.                                                 }3 w/ Z2 e6 a& v4 N, `, c
  377.                                         });* o) p' Q7 _! I5 K5 s
  378.                                 }# O8 f4 }; Q/ l$ z
  379.                         }
    - l" _' W7 D# ]2 P8 Y' V# m' k
  380.                 }3 s2 i* V! y: U& f9 h# {. n% W
  381.         }
    & l6 I2 r3 J1 O, }
  382. }
复制代码
数据库SQLHelper文件
! v0 D) E8 \7 d% x
  1. public class SQLHelper extends SQLiteOpenHelper {
    * S4 i6 o* H5 `: X2 w9 u
  2.         public static final String DB_NAME = "database.db";// 数据库名称
    * v. y3 Y' ^- L* }/ L- _* t
  3.         public static final int VERSION = 1;) d! a" O/ g/ _5 a8 c7 ~' Q; Q
  4.        
    3 t& l, r( F  n2 W
  5.         public static final String TABLE_CHANNEL = "channel";//数据表 6 Y" l4 [8 w' p2 Z% A
  6. 8 M: M" u+ f/ @% ~9 h
  7.         public static final String ID = "id";//- t$ K4 G: b; M4 L, R
  8.         public static final String NAME = "name";- V& E' K) V. ]6 I7 D# j/ ?, ~
  9.         public static final String ORDERID = "orderId";# {% n& O) n8 L/ s; j
  10.         public static final String SELECTED = "selected";
    / ~0 P1 G5 D3 Y& N2 V; v
  11.         private Context context;
    ) ?, N9 w* v/ Y
  12.         public SQLHelper(Context context) {
    - r) y4 {5 }* l$ `
  13.                 super(context, DB_NAME, null, VERSION);
    , Z, t7 k; O; ]1 y8 Z
  14.                 this.context = context;2 v( @6 ]1 f. e; J3 k
  15.         }0 C4 n; d' ]7 ~9 p
  16. " Y, Q( n* G/ f# g; s( @3 ?9 U. n
  17.         public Context getContext(){
      d& O% A8 n( T( C
  18.                 return context;# M' |2 B4 B9 R" C: z3 a  v
  19.         }- s% G! m3 D& Y2 S9 Y
  20.         : M# W( ]* v( B+ h
  21.         @Override
    1 ^; b% d6 p5 P1 j
  22.         public void onCreate(SQLiteDatabase db) {
    . `" ]7 w& N8 t  r8 Y4 u
  23.                 // TODO 创建数据库后,对数据库的操作( r7 `6 d* w( D& Z
  24.                 String sql = "create table if not exists "+TABLE_CHANNEL +! r7 _/ ?5 }) ]! H
  25.                                 "(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +! x4 }- F- _4 u3 K- x
  26.                                 ID + " INTEGER , " +
    # v2 {3 N+ c+ a( N$ J
  27.                                 NAME + " TEXT , " +
    " T: G  l/ G* F8 [
  28.                                 ORDERID + " INTEGER , " +* k$ g: ]# v% q% M( g( g
  29.                                 SELECTED + " SELECTED)";
    * u3 o% `0 G! |0 M! @
  30.                 db.execSQL(sql);
    * C# K) U+ @+ i/ t; D8 ?
  31.         }' ^8 P. N0 u+ L5 |
  32. 0 ^, a: a8 s' b" H% o4 |
  33.         @Override# ?  T3 z9 _# n5 I! A
  34.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    ) V6 W4 t8 S( S+ U. y( {9 o* H4 J
  35.                 // TODO 更改数据库版本的操作# _9 _/ g* F# d# X$ w+ p7 j  d  i
  36.                 onCreate(db);
    / S/ q: n* ~, k7 n+ ?
  37.         }
    4 z" Y. C) U6 |( r; f' @8 d

  38. + m3 A8 Z( |& G' x$ x# s/ K
  39. }; a3 x# n, K  c: N* M
复制代码
注:本DEMO中,加入了长按震动,所以在权限里面记得加上“
4 }& n  ?, w8 A
  1.     <!-- 在SDCard中创建与删除文件权限 -->
    " t3 _( k* p6 g
  2.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    $ v6 W1 e* z1 Q8 S; L5 y$ m: P
  3.     <!-- 往SDCard写入数据权限 -->
    , ~6 w, W  ~7 L: p
  4.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />1 B6 f4 S$ H+ p8 f5 ?
  5.     <!-- 震动权限 -->6 A# }2 Z. B6 T1 h. U3 n5 M
  6.     <uses-permission android:name="android.permission.VIBRATE"/>
复制代码
& \& ^) l. R! I" n) P% [8 p
六、源码下载源码DEMO下载地址如下:! }) @( i$ N, t9 q
游客,如果您要查看本帖隐藏内容请回复
' I* s8 k9 f2 a2 T* `
1 L' s8 s5 i6 I$ S- i, v, [

( ~2 w3 S: f  a- Y& j
发表于 2014-8-9 18:03 | 显示全部楼层
ttedgdfgdfg
发表于 2014-9-5 10:03 | 显示全部楼层
谢谢分享                    
发表于 2014-9-30 10:07 | 显示全部楼层

1 q2 w' Y( W) f! ?% `9 C谢谢分享   
发表于 2014-10-27 21:58 | 显示全部楼层
必须支持楼主
发表于 2014-11-3 16:40 | 显示全部楼层
谢谢楼主,,分享,,下载看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

© 2001-2014Comsenz Inc.

快速回复 返回顶部 返回列表