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

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

[复制链接]
发表于 2014-8-8 11:31 | 显示全部楼层 |阅读模式
距离上次发布Android高仿系列项目:今日头条—新闻阅读器(2)
7 O! d! G# ?5 K3 ?相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下。完善的功能一个一个全部实现后,就放整个源码。开发的进度就是按照一个一个功能的思路走的,所以开发一个小的功能,如果有用,就写一个专门的博客以便有人用到独立的功能可以方便使用。5 i- j# ?. h% ^, x& O9 K; `
这次实现的功能是很多新闻阅读器(网易,今日头条,360新闻等)以及腾讯视频等里面都会出现的频道管理功能。
: V0 s3 ?; [3 K$ o2 q( u
3 f! M" H9 a, z* T1 E

- O: v" G* z  E/ s下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看)2 b' n6 L' h0 b$ B% u5 _- S
4 R1 g1 b/ I7 `' n0 N5 I$ w
7 G, e  {* V2 t& l
1399250647_1821.gif
& N6 o' p% z* x6 N+ I' t4 i% _一、开发心里历程
7 @* S% T2 s6 d4 e5 u
* h3 ]4 G- G' Z9 i! K8 E3 B刚开始接触这个的时候,不知道要如何实现,去网上翻了一大堆资料,懂了个大概,就是目前可以找到的都是拖拽的时候,不带移动动画的,和线上的客户端交互效果相差甚远,在反反复复的尝试查看相关东西,大致的做了出来,目前在模拟器上似乎有一点小BUG,真机测试没有问题,就先放上来,如果发现问题在修改优化。代码反面,没有好好的修改调整,可能会有点乱,请见谅哈。
! r# [8 m, e( x' d
  S% ]8 M9 _% `4 x: @  e# l
/ ~  S" U9 e! {- w9 r+ \
二、开发前的准备
  |# ^" G; U5 O/ j# Y, f& F* o* p/ K" P  f# g* L
1.了解重写View的相关知识,并且知道GridView的一些内部方法,如:怎么通过触摸的坐标获取对应的position等(这里我采用的是继承GridView控件)  A& M# L" P# _/ d/ N) X' B+ _3 T
2.了解屏幕触摸动作传递原理    这里我以前转载的一篇或许会有帮助:Android事件分发机制完全解析,带你从源码的角度彻底理解(全)9 E" t/ ?4 F) H2 z  \9 b4 |' Z

) g5 |! L) _, x2 C1 g$ S3 t3.了解位移动画Animation,本DEMO中主要用到:TranslateAnimation  平移动画/ y5 p/ b6 @) R" h8 s8 k5 ~# m( E+ \
4.了解WindowManager的窗口机制,这里的item拖拽等都要设计到这个。
6 M3 r% E0 d+ A( j2 i5.了解SQLiteDatabase 以及SQLiteOpenHelper等数据库操作相关的类,本DEMO中主要用到数据库进行存储频道信息,如果你要用文档进行存储读取也可以。) l7 L" b0 x+ _+ d* Q6 E' [
. X/ t- @. F+ s: b

* k8 }+ i. ?% H# P: N三、开发思路1.  获取数据库中频道的列表,如果为空,赋予默认列表,并存入数据库,之后通过对应的适配器赋给对应的GridView
1 i3 J# X4 r, M6 t' ~- L
1 h* S# _; l7 ]1 j. {8 M
: l1 t, ]# `1 P4 q4 r) Z
2.  2个GridView--(1.DragGrid   2. OtherGridView)8 Q- O6 H4 \' Z/ r2 R
DragGrid 用于显示我的频道,带有长按拖拽效果" ?4 P% |# H; k3 B/ E/ u
OtherGridView用于显示更多频道,不带推拽效果
6 [  k" q4 b, V注:由于屏幕大小不一定,外层使用ScrollView,所以2者都要重写计算高度
: v: r% e: I, n( E2 a! v
# Z# P6 r( _+ L& G& K( A3 l  c

) ?( }, f, x( c* h# D; a3.  点击2个GridView的时候,根据点击的Item对应的position,获取position对应的view,进行创建一层移动的动画层
9 w' [' q# m( ~2 R# F. U起始位置:点击的positiongetLocationInWindow()获取。终点位置:另一个GridView的最后个ITEM 的position + 1的位置。
, J, c0 @9 v8 Q+ N) m4 e并赋予移动动画,等动画结束后对2者对应的频道列表进行数据的remove和add操作。( p+ |: b0 _5 _* T- ?- @
4 Q0 q/ \# [3 _' Q8 L3 s

% a9 f# G' h: D2 J$ v# f9 D4.  设置点击和拖动的限制条件,如  推荐  这个ITEM是不允许用户操作的。
6 C. G; M" W- l1 h; m( q
* W: ?6 a) ]6 K

6 `- s- U6 T, u8 N5.  拖动的DragGrid的操作:+ ?& Z: i# L6 |" I3 E9 G, l
(1)长按获取长按的ITEM的position  -- dragPosition 以及对应的view ,手指触摸屏幕的时候,调用onInterceptTouchEvent来获取MotionEvent.ACTION_DOWN事件,获取对应的数据。由于这里是继承了GridView,所以长按时间可以通过setOnItemLongClickListener监听来执行,或则你也可以通过计算点击时间来监听是否长按。( i8 W* u  q4 w- a* q0 f, u# \- f
(2)通过onTouchEvent(MotionEvent ev)来监听手指的移动和抬起动作。当它移动到 其它的item下面,并且下方的item对应的position  不等于 dragPosition,进行数据交换,并且2者之间的所有item进行移动动画,动画结束后,数据更替刷新界面。
. b6 K" H  v9 K" i(3) 抬起手后,清除掉拖动时候创建的view,让GridView中的数据显示。
2 p7 x) Z* ?+ e; a
7 ~! N6 P7 i/ F, q

) p& k8 M$ g4 V  y/ {; i6.  退出时候,将改变后的频道列表存入数据库。; C/ u2 [6 C2 n4 I! C

. j0 V/ ~) X* [) x. V9 Y9 x  g3 D

. ^" B. K. d5 K四、流程图下面是大体的流程图:
  Z9 Q: H. ]" l) t 20140504235519968.jpg ( C7 k. ^3 X& g0 s. s' Z7 h
五、核心代码点击进行添加删除:
- J( m  T+ {' g5 R- t
  1. /** GRIDVIEW对应的ITEM点击监听接口  */
    . v/ q6 f2 b) U( g2 _
  2.         @Override1 Y' a' ~' q+ V! d5 |7 o
  3.         public void onItemClick(AdapterView<?> parent, final View view, final int position,long id) {/ F/ d$ h0 a0 x5 e7 G4 i
  4.                 //如果点击的时候,之前动画还没结束,那么就让点击事件无效  A, d0 J7 d7 \. P
  5.                 if(isMove){9 w- ?8 C6 J  o0 _$ v% X
  6.                         return;9 M9 r- l  C2 H
  7.                 }
    3 o) |, d$ H! J
  8.                 switch (parent.getId()) {$ e( J7 I, [) U# O" n
  9.                 case R.id.userGridView:
    3 N0 \3 T5 |/ |' V* s
  10.                         //position为 0,1 的不可以进行任何操作# _* h) F( y0 o) G( j+ j' s0 Z
  11.                         if (position != 0 && position != 1) {
    3 E: _4 C; B. P  Q0 X
  12.                                 final ImageView moveImageView = getView(view);$ h6 v6 N+ H1 n/ P
  13.                                 if (moveImageView != null) {
    + _% p6 M( F2 j
  14.                                         TextView newTextView = (TextView) view.findViewById(R.id.text_item);
      L3 ?; M4 ~1 L8 V. |/ X+ S  c
  15.                                         final int[] startLocation = new int[2];6 J  P# w7 k0 _, j
  16.                                         newTextView.getLocationInWindow(startLocation);
    ! D; N: ^4 h) s/ g6 H2 ]5 T* ?& ^
  17.                                         final ChannelItem channel = ((DragAdapter) parent.getAdapter()).getItem(position);//获取点击的频道内容# F+ U. j2 w9 m! V
  18.                                         otherAdapter.setVisible(false);
    2 z8 ]; c- x4 k' `
  19.                                         //添加到最后一个
    # S( d" O* j) q! V4 r( _3 F
  20.                                         otherAdapter.addItem(channel);
    & b- D/ o6 E# B! l% H* s+ j
  21.                                         new Handler().postDelayed(new Runnable() {% `, @& b: y- f
  22.                                                 public void run() {
    " ]) ]6 j% W8 g" f' B
  23.                                                         try {
    7 ]# h) D- N# ]  A
  24.                                                                 int[] endLocation = new int[2];
    * b$ ~. P9 E) M7 y2 ]
  25.                                                                 //获取终点的坐标% l9 {4 ~2 j; E! y
  26.                                                                 otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);9 R: |5 I" O$ _9 O3 j7 `- G% b
  27.                                                                 MoveAnim(moveImageView, startLocation , endLocation, channel,userGridView);7 ?+ _/ n8 g- T9 B7 c  o
  28.                                                                 userAdapter.setRemove(position);
    3 M" n/ H. g# R) o$ F& p
  29.                                                         } catch (Exception localException) {
    8 P1 k' `/ R6 \& T
  30.                                                         }0 C) m  s0 @& j) v: X
  31.                                                 }
    / h/ v0 s7 J1 m- w: z5 c. l9 S1 T
  32.                                         }, 50L);. j) t$ G! z; {7 }6 s6 E* y
  33.                                 }8 ~7 e" m' w% C# J- x
  34.                         }& I, e* E7 x) Z" `
  35.                         break;- p$ Y$ R: Z  ~& j3 Z
  36.                 case R.id.otherGridView:1 Z" v9 e% i6 O! s
  37.                         final ImageView moveImageView = getView(view);
    ' l3 N$ E/ _, x3 l0 A* {
  38.                         if (moveImageView != null){
    - P! {/ L3 e. F1 `
  39.                                 TextView newTextView = (TextView) view.findViewById(R.id.text_item);9 E8 s) k$ X; f" F1 q
  40.                                 final int[] startLocation = new int[2];7 M1 |# U' R1 {. ~) d
  41.                                 newTextView.getLocationInWindow(startLocation);& W2 U% d) ^) c1 \7 U" U4 \
  42.                                 final ChannelItem channel = ((OtherAdapter) parent.getAdapter()).getItem(position);
      I% S- B- Z/ n" P; ~8 g+ a
  43.                                 userAdapter.setVisible(false);1 H) Q2 O2 `# h4 N6 w, Z% g7 @* [
  44.                                 //添加到最后一个. _( V" A. X/ g  \3 g
  45.                                 userAdapter.addItem(channel);
    ) L  m- D; o& y! |
  46.                                 new Handler().postDelayed(new Runnable() {
    ! W+ W) e: M1 {
  47.                                         public void run() {
    ; G7 ]$ U9 f) w* G! D/ Y
  48.                                                 try {
    # T% P( n5 y9 _
  49.                                                         int[] endLocation = new int[2];
    2 v; f: C+ Q! M8 N" r1 V" i
  50.                                                         //获取终点的坐标
    2 S0 S* |. C2 R% ~# x1 L/ C4 v
  51.                                                         userGridView.getChildAt(userGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
    9 ]6 c. r% v0 e( c
  52.                                                         MoveAnim(moveImageView, startLocation , endLocation, channel,otherGridView);
    % t  A' J2 F8 P) L0 q1 D
  53.                                                         otherAdapter.setRemove(position);
    6 W. }8 z/ Z' H
  54.                                                 } catch (Exception localException) {
    . Z; \, n5 k2 N0 l/ h0 A
  55.                                                 }2 C& E5 }) @6 i' Z
  56.                                         }
    7 m3 r: f, ^2 D. }4 I- C$ v
  57.                                 }, 50L);2 ^6 B* y! E5 Q. v: d
  58.                         }& ?% \4 K: _0 `$ b$ q; C: ?
  59.                         break;
    6 i3 `; T  M" E2 c
  60.                 default:
    : {7 M) e' p4 D5 M8 n
  61.                         break;
    / x- S2 E+ I7 i% q4 p$ `
  62.                 }
    - T. V1 K9 N" D; ?+ c
  63.         }
复制代码
移动动画:
* A: G2 r* @; {
  1. <span style="font-size:14px;">private void MoveAnim(View moveView, int[] startLocation,int[] endLocation, final ChannelItem moveChannel,
    ; ~, e& n0 o  w6 ?  U# Q
  2.                         final GridView clickGridView) {7 B4 p% S! m* K' P& D
  3.                 int[] initLocation = new int[2];
    ' f" P" a! @& h6 E7 \$ g( A, B
  4.                 //获取传递过来的VIEW的坐标
    1 D9 d( r! @" [7 ]( |- M' t% U- l
  5.                 moveView.getLocationInWindow(initLocation);5 f. u; e. t, @1 I4 a8 |7 x
  6.                 //得到要移动的VIEW,并放入对应的容器中' q4 J( U5 r' j+ x* L$ u
  7.                 final ViewGroup moveViewGroup = getMoveViewGroup();+ G8 K- m1 e: r! d2 v
  8.                 final View mMoveView = getMoveView(moveViewGroup, moveView, initLocation);# ^+ x0 a6 E9 [" ?1 u% u' _. _
  9.                 //创建移动动画3 ^: E( L! I5 N2 F- [( J0 n" J* _7 p
  10.                 TranslateAnimation moveAnimation = new TranslateAnimation(
    % K$ G/ [8 Y% {& S% \. ^8 v; Q
  11.                                 startLocation[0], endLocation[0], startLocation[1],2 X: q2 k/ O. L! g9 b5 f4 C) P
  12.                                 endLocation[1]);' J! `6 W; _+ p, c5 I
  13.                 moveAnimation.setDuration(300L);//动画时间: g; C8 g5 L& I
  14.                 //动画配置
    ) y) e" N. b+ U- |+ A
  15.                 AnimationSet moveAnimationSet = new AnimationSet(true);
    - F- X% `3 x* |9 Y9 `
  16.                 moveAnimationSet.setFillAfter(false);//动画效果执行完毕后,View对象不保留在终止的位置5 T- @9 G7 a) ]9 f  q* h  L4 D
  17.                 moveAnimationSet.addAnimation(moveAnimation);
    1 h7 N7 _9 a. E# K9 v: W5 _7 w
  18.                 mMoveView.startAnimation(moveAnimationSet);
    : t0 l) a# i& Q" p# D
  19.                 moveAnimationSet.setAnimationListener(new AnimationListener() {" m* `# Y2 U, q; k! E. {" y
  20.                         
    " J, ~5 k3 b8 m' G! I
  21.                         @Override
    / U; \8 ~# \! p% D7 N/ k
  22.                         public void onAnimationStart(Animation animation) {9 g2 A. I1 _0 n# L; X
  23.                                 isMove = true;) p: m2 c4 |$ Z+ D
  24.                         }+ ?5 v# `( _/ K$ I3 c0 t* W
  25.                         
    2 ?& W% e8 a) j
  26.                         @Override7 I7 g4 G5 V1 w/ ~
  27.                         public void onAnimationRepeat(Animation animation) {
    + G* c& e, z( R1 y* R
  28.                         }" p8 T4 s! S- E, X: F' \8 ~, S1 K! u
  29.                         % j2 A; g! T: N* W+ T$ h
  30.                         @Override
    ' P* F. s2 f6 Y, ^
  31.                         public void onAnimationEnd(Animation animation) {
    : M% L8 |$ I, ]9 _/ ~
  32.                                 moveViewGroup.removeView(mMoveView);: B/ p4 E" B; R, i
  33.                                 // instanceof 方法判断2边实例是不是一样,判断点击的是DragGrid还是OtherGridView
    1 r& m7 I8 |8 M+ W0 B# p
  34.                                 if (clickGridView instanceof DragGrid) {- S) ~( f/ B4 g) ]' q) S' q
  35.                                         otherAdapter.setVisible(true);- H7 K! M! r/ C" Y+ U' ]
  36.                                         otherAdapter.notifyDataSetChanged();& n! R+ J& M- y, U* [; d, r" w
  37.                                         userAdapter.remove();
    : p; e, z# |9 Z
  38.                                 }else{
    3 y0 g) y7 i. E0 L0 M
  39.                                         userAdapter.setVisible(true);% r/ v% {* }  n/ D$ C, l: a6 {: J
  40.                                         userAdapter.notifyDataSetChanged();( M; m- X0 f  z' G; Q
  41.                                         otherAdapter.remove();( B. N. v& D+ n
  42.                                 }7 D* N9 n" O& l: y
  43.                                 isMove = false;
    ( u/ i3 m8 W; U+ h! H. a
  44.                         }
    % p) f. z/ T+ S7 k" m, N8 [$ ~- ]
  45.                 });
    1 q8 h$ q  O% n3 N, ~" E4 Q
  46.         }</span>
复制代码
9 E& e. w" J% ?
7 O/ ~3 H8 @- @8 O5 S: m
5 x( y( k) D/ j  z" e$ a# @7 [
 楼主| 发表于 2014-8-8 11:34 | 显示全部楼层
可拖拽的DragGrid代码:( \; h1 r+ Y% g: [' A, P
  1. public class DragGrid extends GridView {" q" y/ ]7 Q) k; i
  2.         /** 点击时候的X位置 */# e  M% v2 t2 J; S
  3.         public int downX;
    2 `# w3 U! x3 R/ }, Q  {
  4.         /** 点击时候的Y位置 */. D/ |: A2 e: b) A# x
  5.         public int downY;
    4 K8 G0 E5 l  D- `# F9 a# B
  6.         /** 点击时候对应整个界面的X位置 */0 v0 }5 T5 V+ ^; s; x. t
  7.         public int windowX;: M( d9 c( o# q4 U- z# ~4 w
  8.         /** 点击时候对应整个界面的Y位置 */
    & v" c4 k- x: n" r6 G
  9.         public int windowY;; D7 d/ s1 I  {. l% O5 K, Q! o
  10.         /** 屏幕上的X */- A# X8 H3 ]: s+ L
  11.         private int win_view_x;
    1 s! S/ n' T! U* j9 s% z
  12.         /** 屏幕上的Y */& C& u  r8 F6 I: s) U
  13.         private int win_view_y;" V7 G; i2 q# B2 }
  14.         /** 拖动的里x的距离 */
    % I" P0 f. P9 A6 x7 V
  15.         int dragOffsetX;
    ! X$ {7 P3 Q8 d8 \" p* O
  16.         /** 拖动的里Y的距离 */- e1 x5 E3 e+ b" H" I/ B
  17.         int dragOffsetY;
    ( P$ ~# k; U* o) t$ O4 |1 p
  18.         /** 长按时候对应postion */' p4 q7 d( c3 E# `8 U0 R$ e  x0 \
  19.         public int dragPosition;4 a7 w  Y' L- @) b+ i  r
  20.         /** Up后对应的ITEM的Position */' P( V& ]% c- N4 x+ E+ j7 U
  21.         private int dropPosition;
    7 u' R+ E) O% i2 M* T' A
  22.         /** 开始拖动的ITEM的Position */
    0 K. W. {6 S  Q% K1 v$ o3 Y
  23.         private int startPosition;
    , ?/ Z. k& N& z: O6 Y6 A( |% \
  24.         /** item高 */
    + ~. ~: a. S% a( d3 }8 P+ l
  25.         private int itemHeight;
      {+ W4 @: _6 s0 U
  26.         /** item宽 */
      L0 d8 N  ^# |. ~7 J
  27.         private int itemWidth;
    5 ~8 Y5 R# j# A1 s* K* }# F5 d1 J
  28.         /** 拖动的时候对应ITEM的VIEW */
    . X. Q+ t+ P* l9 m+ O, T
  29.         private View dragImageView = null;5 e8 O8 u! d: U9 `( M
  30.         /** 长按的时候ITEM的VIEW */: k/ X- _5 o6 w( n
  31.         private ViewGroup dragItemView = null;
    $ ~; E, o6 l! B
  32.         /** WindowManager管理器 */2 z4 C; {0 L( N7 A3 W( W$ k
  33.         private WindowManager windowManager = null;
    5 i# d. N" Z7 }9 J" v: F* o4 ]# N( Y
  34.         /** */
    ( i# A" L  L* D
  35.         private WindowManager.LayoutParams windowParams = null;
    1 O9 W& C& U- R4 N0 ^! e9 F8 g9 O) s
  36.         /** item总量 */3 R0 A& E% w- |/ X$ I: [
  37.         private int itemTotalCount;
    ; A7 V( |" t  u4 F! A, [2 O
  38.         /** 一行的ITEM数量 */2 n( L5 w8 ]$ C" f
  39.         private int nColumns = 4;2 `) k: l$ q" R: a5 i/ Y4 _
  40.         /** 行数 */3 u2 G! @1 q6 l8 U$ V
  41.         private int nRows;
    1 l- t7 t1 B9 M) b# G0 c6 G
  42.         /** 剩余部分 */9 J/ W' ^; b* }
  43.         private int Remainder;. {6 V$ s: w: H$ W) M6 O" S
  44.         /** 是否在移动 */
    ( u. r) u* c; h) D) h5 z
  45.         private boolean isMoving = false;" X8 D0 l1 U! k2 \
  46.         /** */  z% F( d5 m  p
  47.         private int holdPosition;' W1 T+ R8 C' J( U. [4 E( x+ k/ m) a
  48.         /** 拖动的时候放大的倍数 */2 ~) O  A9 J8 r) C# |7 y% u
  49.         private double dragScale = 1.2D;+ M/ Q7 t% J1 H, r
  50.         /** 震动器 */4 }  r0 X: j! S0 e
  51.         private Vibrator mVibrator;
    0 m) ?. Y  u% X
  52.         /** 每个ITEM之间的水平间距 */
    + Y0 e& ^6 M- F# a7 g, Y
  53.         private int mHorizontalSpacing = 15;
    ; Y$ [, K8 N7 V7 s0 M
  54.         /** 每个ITEM之间的竖直间距 */
      A! s# o7 }( l' Y
  55.         private int mVerticalSpacing = 15;' [, m$ o' m* b8 k, i
  56.         /* 移动时候最后个动画的ID */3 g  R3 y5 W" e& x2 N' m3 i  }
  57.         private String LastAnimationID;* ?$ Q" ~# A4 }* }3 D& I

  58. # h0 u3 b/ j, s. @
  59.         public DragGrid(Context context) {
    + s% I7 q9 x9 t( t$ d9 I' f6 t
  60.                 super(context);, Z4 v& K8 s( z3 C9 i7 C
  61.                 init(context);
    + z) a5 P3 D. `6 p8 O
  62.         }7 v/ p9 N4 }5 a, ^3 m

  63. ; Q$ `# g+ }3 m0 L( O. {
  64.         public DragGrid(Context context, AttributeSet attrs, int defStyle) {
    - G  ^; b" h' L' m2 I0 `
  65.                 super(context, attrs, defStyle);
      H# L0 X$ ]  w- e6 t
  66.                 init(context);
    0 B" G- {; x( t: {2 E4 C/ F! s
  67.         }5 o* m: {# z, g8 _* V/ `
  68. ) \9 O! f$ ]  P
  69.         public DragGrid(Context context, AttributeSet attrs) {
    6 P# K  n3 ]8 X
  70.                 super(context, attrs);% X. q7 K+ z! B% n
  71.                 init(context);
    ) M. }& ^" B0 e  B- V; W% S8 I( V
  72.         }
    ! [6 X: l5 A3 ]% x, E# E
  73. / M" i& r( w, S
  74.         public void init(Context context) {( D, Y  x0 N3 n. T2 j: {6 m
  75.                 mVibrator = (Vibrator) context- `- H, \1 K+ R0 X% ?- O+ T0 Y
  76.                                 .getSystemService(Context.VIBRATOR_SERVICE);; T) o. L/ q- a; y% k- ~
  77.                 // 将布局文件中设置的间距dip转为px, A/ s  r; v# o2 {
  78.                 mHorizontalSpacing = DataTools.dip2px(context, mHorizontalSpacing);
    ) c/ R/ Z* x  @6 p& u$ \
  79.         }
    6 @+ `, ~( h* _. C2 ]$ F
  80. + m8 Q& g" P/ L$ _3 Z
  81.         @Override# x  ~3 w* M. N
  82.         public boolean onInterceptTouchEvent(MotionEvent ev) {1 i& e# U* Y* P$ X# S+ a/ ?5 [
  83.                 // TODO Auto-generated method stub
    % y- @2 |/ Q" y! i9 v# K; a# @
  84.                 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
    ' M- r7 [' R4 M
  85.                         downX = (int) ev.getX();
    / J7 K& K4 X2 W! m5 G! N* K
  86.                         downY = (int) ev.getY();$ o9 a# ~% m' x. C' Z: G
  87.                         windowX = (int) ev.getX();3 s8 c. n; T1 C( p3 X! X+ ]4 v
  88.                         windowY = (int) ev.getY();
    6 }# U* Y: Y2 k( r% `5 h  S
  89.                         setOnItemClickListener(ev);  H: k( k* a' R
  90.                 }
    ' y. w6 \1 u. l. L5 ]9 o  C" C
  91.                 return super.onInterceptTouchEvent(ev);
    7 n4 F4 h0 O" k! Q: B7 x& H
  92.         }( X2 K) b8 o) w7 N
  93. & ^% H/ ?/ r4 B% f/ ]1 U
  94.         @Override
    ! p, X0 p& h' e4 e! A1 g
  95.         public boolean onTouchEvent(MotionEvent ev) {
    : w8 M# t3 F, O" D
  96.                 // TODO Auto-generated method stub
    8 w( g/ K7 V8 y6 {3 Y2 i; }5 L
  97.                 boolean bool = true;
    . s) C" b& x. A' u
  98.                 if (dragImageView != null9 l. @2 ?7 t3 C( K5 U; `, S: e# @  Z9 e
  99.                                 && dragPosition != AdapterView.INVALID_POSITION) {
    , e3 ]2 i. A0 J+ b5 Z
  100.                         // 移动时候的对应x,y位置
    * G% h! G0 c9 v7 z  I& P% z- ^
  101.                         bool = super.onTouchEvent(ev);2 b" q- b1 |& B# f* C
  102.                         int x = (int) ev.getX();
    1 f2 N: K- `% n2 M- B% z
  103.                         int y = (int) ev.getY();
    6 p6 I2 Q' {2 [$ G
  104.                         switch (ev.getAction()) {+ r: @+ ~$ W! j0 g0 Z
  105.                         case MotionEvent.ACTION_DOWN:1 }  j" {  h  D' C
  106.                                 downX = (int) ev.getX();
    8 ^" N" l8 I! p6 d
  107.                                 windowX = (int) ev.getX();
    * e. C5 ~3 H7 O) C$ K
  108.                                 downY = (int) ev.getY();
    / f( u0 G1 Z6 h( j$ q9 W2 C
  109.                                 windowY = (int) ev.getY();
    ! O! R1 t9 S: R2 {. i) j# X
  110.                                 break;; c3 V$ G- w" |* j
  111.                         case MotionEvent.ACTION_MOVE:
    . d  Y; ~% s% d7 `0 c% n/ [6 ]
  112.                                 onDrag(x, y, (int) ev.getRawX(), (int) ev.getRawY());
    # z" N2 Z, _) U
  113.                                 if (!isMoving) {* e9 P2 [3 d8 x8 \
  114.                                         OnMove(x, y);/ j- d- [/ {! k; e5 A
  115.                                 }$ H/ g: e, @" ?6 K6 X# f- v
  116.                                 if (pointToPosition(x, y) != AdapterView.INVALID_POSITION) {* _$ X  m9 |5 t# ]8 }% D
  117.                                         break;
    * s+ L2 M- c7 D# o* V" _
  118.                                 }) {4 \0 [7 e/ S7 ?+ A4 X
  119.                                 break;% a/ ^7 A3 f' H5 w& ~6 T  K* G( ~
  120.                         case MotionEvent.ACTION_UP:( d  {5 J2 k+ d( D
  121.                                 stopDrag();5 t5 B" S- f6 D. D, L5 J
  122.                                 onDrop(x, y);
    2 v# t& Z' A5 G) y
  123.                                 requestDisallowInterceptTouchEvent(false);( P. a: E9 C$ }! V# L
  124.                                 break;
    : T: Q) _0 {( {  t
  125. 9 H! A8 g' p1 ^+ E" ]. d
  126.                         default:5 ~& Q) I& j; n2 A
  127.                                 break;
    + i6 ^' y) e5 ?" t+ v: }
  128.                         }
    ' Q& @7 w: W4 r% |
  129.                 }
    3 T, b4 y  d  I1 ^3 a2 w
  130.                 return super.onTouchEvent(ev);) o" n2 G' @4 \' k2 Y
  131.         }& h3 ]7 Z6 ?( k: e% \4 {

  132. 7 C- Z' w7 A# p" |6 |6 A
  133.         /** 在拖动的情况 */  L8 h1 Q* G/ ]; j
  134.         private void onDrag(int x, int y, int rawx, int rawy) {
    / b1 I) E% T- ~
  135.                 if (dragImageView != null) {
    : `3 o, E4 e$ I0 F
  136.                         windowParams.alpha = 0.6f;1 B; B0 @5 e5 h, o2 S: P
  137.                         windowParams.x = rawx - win_view_x;
    6 I& Y. j# ?$ k, g- Q
  138.                         windowParams.y = rawy - win_view_y;% D9 i1 j$ X+ l' ~' N# o* l. U
  139.                         windowManager.updateViewLayout(dragImageView, windowParams);
    + l  u# f! P9 N0 U# c1 s
  140.                 }( ]/ L2 F* E5 ]+ n1 l, n
  141.         }
    ' k' _1 q/ H7 O# E
  142. ) ?& v9 ]; Q& X+ s+ u; f# \
  143.         /** 在松手下放的情况 */8 a, o6 c5 X' M0 T+ V% Z* |
  144.         private void onDrop(int x, int y) {& y: R) g. ?7 z, {. I6 m. Z$ A
  145.                 // 根据拖动到的x,y坐标获取拖动位置下方的ITEM对应的POSTION2 G/ C# W4 G. z& z- m. l
  146.                 int tempPostion = pointToPosition(x, y);* t' m' }  e1 Q6 h' W
  147.                 dropPosition = tempPostion;& q6 r1 D/ n6 k! @) ~' Y4 X5 b0 |
  148.                 DragAdapter mDragAdapter = (DragAdapter) getAdapter();3 g  K5 b  \6 s9 ^+ w( L  N4 a
  149.                 // 显示刚拖动的ITEM0 l  [$ ?7 ^- ]% Y$ }
  150.                 mDragAdapter.setShowDropItem(true);
    7 R' p/ v) Y7 n- O% ?$ B2 _
  151.                 // 刷新适配器,让对应的ITEM显示3 P, A5 U* d7 y  V6 L
  152.                 mDragAdapter.notifyDataSetChanged();
    9 @! v' t3 d& _3 P4 Y& N5 s+ U
  153.         }
    - T1 d: ~. I  n2 C- O: H  \

  154. , P: R. p. M9 F( d1 l
  155.         /**
    4 r# |/ m, |1 I( f
  156.          * 长按点击监听& {5 D" p# V) `3 H# x6 W
  157.          * @param ev5 _- J9 L% L% P% O, R
  158.          */
    * K3 p3 B. m1 X- x' E6 X! ]% F. B
  159.         public void setOnItemClickListener(final MotionEvent ev) {( F' Y1 g7 z1 S; X: x+ o4 {) j+ G; r
  160.                 setOnItemLongClickListener(new OnItemLongClickListener() {4 s. r& k  v$ o+ C. ?; r

  161. 2 s$ {- W3 R: s; \* B! F: r
  162.                         @Override) R+ a+ w( |: S; D) d( A
  163.                         public boolean onItemLongClick(AdapterView<?> parent, View view,/ O% ^2 O' w- _/ x$ M/ p$ n
  164.                                         int position, long id) {4 k( q; l8 O) x" t$ b
  165.                                 int x = (int) ev.getX();// 长安事件的X位置( i& a$ R) N# v; o
  166.                                 int y = (int) ev.getY();// 长安事件的y位置
    1 F5 {# p' l( a8 s: n$ b" i& ~& Y
  167.                                 startPosition = position;// 第一次点击的postion+ [8 z# v# T( w0 j( {3 n
  168.                                 dragPosition = position;
    4 w) }; M- T' ]8 o' m
  169.                                 if (startPosition <= 1) {
    * S+ m) e7 P8 j1 W6 \7 i
  170.                                         return false;% W7 t# h, G  N2 H8 T  u
  171.                                 }2 E8 B9 y) t/ U( s6 }: {& u
  172.                                 ViewGroup dragViewGroup = (ViewGroup) getChildAt(dragPosition0 p9 W: z1 z) e& y; A
  173.                                                 - getFirstVisiblePosition());
    ! q, ~8 q3 Q( h' [9 ?
  174.                                 TextView dragTextView = (TextView) dragViewGroup7 T3 Y& L" x+ ?$ U- W! a
  175.                                                 .findViewById(R.id.text_item);
    5 O% o0 l! {1 R6 ~+ k: v5 A
  176.                                 dragTextView.setSelected(true);# X( {3 c2 {/ ]4 _6 e8 `& u) P+ p
  177.                                 dragTextView.setEnabled(false);6 T1 N* {6 T5 K1 d: Y; A8 ^
  178.                                 itemHeight = dragViewGroup.getHeight();9 ?9 Y7 Q+ H* G, k/ m4 P( y$ G' ?7 p  O
  179.                                 itemWidth = dragViewGroup.getWidth();8 Z  B/ W5 r' Y
  180.                                 itemTotalCount = DragGrid.this.getCount();6 j/ g1 {' X3 T  ]5 o$ X9 ?
  181.                                 int row = itemTotalCount / nColumns;// 算出行数, l* K% n5 o+ n7 c1 v' f
  182.                                 Remainder = (itemTotalCount % nColumns);// 算出最后一行多余的数量
      i9 s: D: T9 V# O4 l% I' M9 p+ q
  183.                                 if (Remainder != 0) {, k1 [) s! l! h( b: Z7 k3 N& f
  184.                                         nRows = row + 1;: R4 Y) \7 H0 G1 V- l6 k- ]* {
  185.                                 } else {- Q3 q- n6 x( i6 v4 @/ s
  186.                                         nRows = row;
    9 M0 _% b* Y6 c* S3 F) G* P
  187.                                 }
    # \# X+ v5 n" _0 e9 x
  188.                                 // 如果特殊的这个不等于拖动的那个,并且不等于-1
    * @8 z( x* A% {" @" O
  189.                                 if (dragPosition != AdapterView.INVALID_POSITION) {- c* v2 U1 J- B% e
  190.                                         // 释放的资源使用的绘图缓存。如果你调用buildDrawingCache()手动没有调用setDrawingCacheEnabled(真正的),你应该清理缓存使用这种方法。' H+ X, d4 q6 [+ Q
  191.                                         win_view_x = windowX - dragViewGroup.getLeft();// VIEW相对自己的X,半斤
    - u  b: Q4 l* {3 {. s0 e- u
  192.                                         win_view_y = windowY - dragViewGroup.getTop();// VIEW相对自己的y,半斤
    . B) N& d; {' E  y2 X4 U: z) F
  193.                                         dragOffsetX = (int) (ev.getRawX() - x);// 手指在屏幕的上X位置-手指在控件中的位置就是距离最左边的距离
    - R( l& Q9 ?6 g
  194.                                         dragOffsetY = (int) (ev.getRawY() - y);// 手指在屏幕的上y位置-手指在控件中的位置就是距离最上边的距离
    0 y* c. N! o) V& L& q1 x
  195.                                         dragItemView = dragViewGroup;! Z/ R# C" |2 r
  196.                                         dragViewGroup.destroyDrawingCache();. s8 G4 G7 I; I8 z8 ~* w
  197.                                         dragViewGroup.setDrawingCacheEnabled(true);. H; x) V2 v4 S& U$ X+ ^
  198.                                         Bitmap dragBitmap = Bitmap.createBitmap(dragViewGroup
    . A9 e8 H; m  P1 t* k
  199.                                                         .getDrawingCache());2 D8 i: i! C4 _8 g
  200.                                         mVibrator.vibrate(50);// 设置震动时间
    - ^7 I8 m6 G( U$ c# s6 t  \+ Y
  201.                                         startDrag(dragBitmap, (int) ev.getRawX(),( ]+ x' d5 k8 d. g% S4 x$ ?
  202.                                                         (int) ev.getRawY());
    9 C( z) E/ i/ B7 C; U) h
  203.                                         hideDropItem();/ V3 O5 z) h- f  H; w  l5 s+ D+ Q
  204.                                         dragViewGroup.setVisibility(View.INVISIBLE);( a6 A" `/ E9 m# u$ |- W/ r
  205.                                         isMoving = false;! D! W: \% r8 |7 f" N0 T
  206.                                         requestDisallowInterceptTouchEvent(true);
    8 ?1 Q9 \8 I, b/ n% P# p. H
  207.                                         return true;/ S8 s  |# l* j: c
  208.                                 }
    7 e% j3 k, W/ U/ R) J0 D
  209.                                 return false;
    6 O% ^( o! |* O( h% n4 C. A+ d; z
  210.                         }
    . q2 N! H! X6 {1 S+ W5 I
  211.                 });, F- W/ S, Q6 C* O6 S. ~0 k. q
  212.         }
    - O& x/ ?) _+ _6 M! W

  213. , X7 O7 U- k0 P5 l& q. M4 c& S
  214.         public void startDrag(Bitmap dragBitmap, int x, int y) {
    & q9 `% H* ?- Z- ~5 s& L
  215.                 stopDrag();
    & k; }1 Y! r, l/ |; z# |/ ^2 b
  216.                 windowParams = new WindowManager.LayoutParams();// 获取WINDOW界面的
      ^! r* G# w$ b+ H8 E
  217.                 // Gravity.TOP|Gravity.LEFT;这个必须加
    7 E6 t; e8 {* m( S, Q
  218.                 windowParams.gravity = Gravity.TOP | Gravity.LEFT;; _6 l& L3 W3 {. c2 d8 S. B
  219.                 // 得到preview左上角相对于屏幕的坐标, g( g& k5 e6 M  V4 M! H
  220.                 windowParams.x = x - win_view_x;
    8 [) M+ x7 P) }0 B+ J1 m; g7 R
  221.                 windowParams.y = y - win_view_y;
    # G' P  @: R' h9 A# d7 N2 f
  222.                 // 设置拖拽item的宽和高3 C. f3 z' E$ K6 J6 o' F
  223.                 windowParams.width = (int) (dragScale * dragBitmap.getWidth());// 放大dragScale倍,可以设置拖动后的倍数* }- I8 m4 t& N, t1 \' Y
  224.                 windowParams.height = (int) (dragScale * dragBitmap.getHeight());// 放大dragScale倍,可以设置拖动后的倍数
    $ U* ^9 g% J/ m  T5 v0 \' V
  225.                 this.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE2 m, ], a% {9 G  Q
  226.                                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE/ c3 g0 O- z: f6 L3 Y7 _
  227.                                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
    ( B: u% H7 J) \
  228.                                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;8 ?* C( X$ Z( A- i  r, G; n
  229.                 this.windowParams.format = PixelFormat.TRANSLUCENT;
    " f; l7 Y: R) X9 O
  230.                 this.windowParams.windowAnimations = 0;2 P2 R! x3 J8 h/ a* p1 b
  231.                 ImageView iv = new ImageView(getContext());& |( ~+ h$ M1 Z6 z; f7 _9 j
  232.                 iv.setImageBitmap(dragBitmap);0 n9 d: C0 ?( `. M" M& X8 R" w
  233.                 windowManager = (WindowManager) getContext().getSystemService(
    7 |- {1 y: S) S6 }" I. s
  234.                                 Context.WINDOW_SERVICE);// "window"
    7 L( l$ O# y, m! j, ]1 c8 A7 c
  235.                 windowManager.addView(iv, windowParams);7 F9 n7 O8 V1 O3 o5 o
  236.                 dragImageView = iv;; L' i4 {4 C# a4 O2 f6 D
  237.         }& I$ o9 i$ B* T7 T& U% L1 ~
  238. 1 T4 S0 `! E: y/ Z8 E0 x
  239.         /** 停止拖动 ,释放并初始化 */5 |, U$ K+ Z4 K- D; W' ^
  240.         private void stopDrag() {
    , O% [9 C1 ^% C7 m2 u4 B
  241.                 if (dragImageView != null) {
    4 P( _# _) X! L5 w' m( e
  242.                         windowManager.removeView(dragImageView);  l5 c% y% E% z% }& C
  243.                         dragImageView = null;
    + l# O& X' m. {% A
  244.                 }
    . Q' i& h2 ~! o
  245.         }1 K. e1 p+ j, ]& h* e  J
  246. , b0 e- W+ V) a+ c" o5 S& |
  247.         /** 在ScrollView内,所以要进行计算高度 */
    , p& ]6 t, b0 y! l9 ^# }- P
  248.         @Override1 M4 s- D$ w+ v# n9 }8 r* x
  249.         public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    ' D' g% g& u: h, d# [/ z9 I
  250.                 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,% B5 U6 ]+ O7 j4 B  i9 C
  251.                                 MeasureSpec.AT_MOST);
    8 D0 b& J; m2 G8 S- c# `
  252.                 super.onMeasure(widthMeasureSpec, expandSpec);0 i2 Y, w/ C* l7 V8 ?
  253.         }- t9 i! |5 C/ r' O* u/ l
  254. : g$ s" o" g4 `2 y  e( R
  255.         /** 隐藏 放下 的ITEM */
    6 C  R+ r, D/ H
  256.         private void hideDropItem() {) K: Z  Q- X  E2 |$ |5 x  T
  257.                 ((DragAdapter) getAdapter()).setShowDropItem(false);4 U1 F) w( ~  T1 M( z/ j
  258.         }3 T4 B& D- L. y$ L% X6 t
  259. 2 S0 u% x' n+ [: Q
  260.         /** 获取移动动画 */
    5 P: }  E& X: X* c
  261.         public Animation getMoveAnimation(float toXValue, float toYValue) {$ e0 s* b8 ]/ F) w7 B  W1 H& M0 p3 H
  262.                 TranslateAnimation mTranslateAnimation = new TranslateAnimation(
      }! |) {3 Y3 E% V7 L
  263.                                 Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,
    9 m! R! E: F  {! S4 ]! z8 P. Q0 Y; `
  264.                                 toXValue, Animation.RELATIVE_TO_SELF, 0.0F,/ A2 a8 O4 X$ G" G6 E/ v8 ~
  265.                                 Animation.RELATIVE_TO_SELF, toYValue);// 当前位置移动到指定位置" M  k$ c8 p& w4 P) U) L* L2 c
  266.                 mTranslateAnimation.setFillAfter(true);// 设置一个动画效果执行完毕后,View对象保留在终止的位置。) q2 z. B2 F5 }+ G- B
  267.                 mTranslateAnimation.setDuration(300L);
    ; h- c- A: Z1 E+ _0 s! N% L
  268.                 return mTranslateAnimation;
    ' v- u0 s* I1 |
  269.         }
    " f: z  Q# S, a: x+ N
  270. 9 g) `$ E9 U5 ^( D( {. P
  271.         /** 移动的时候触发 */
    : L2 M" e' F- B9 W( A
  272.         public void OnMove(int x, int y) {4 y% K" ?+ E( M+ ]/ ]  \8 ^/ ]8 W
  273.                 // 拖动的VIEW下方的POSTION" R9 |6 m8 N/ E; [. J
  274.                 int dPosition = pointToPosition(x, y);
    & ^& v, Y6 @; a; y2 a% l/ v7 a1 ]. s
  275.                 // 判断下方的POSTION是否是最开始2个不能拖动的
    $ C6 d% Y- g: ?# ?2 W$ `
  276.                 if (dPosition > 1) {# T$ |! ?+ M: S0 Y, j
  277.                         if ((dPosition == -1) || (dPosition == dragPosition)) {
    0 K2 L* J( `; W( q
  278.                                 return;
    " P" H- Z1 v; }8 t
  279.                         }
    1 ?" Y5 C6 U$ \; E. p9 `1 B
  280.                         dropPosition = dPosition;
    ! f! k5 l2 I$ W
  281.                         if (dragPosition != startPosition) {
    ! R& l* a. g- x+ r
  282.                                 dragPosition = startPosition;
    + S* @, t/ u  T8 z7 ^6 J
  283.                         }
    & ^; x# J" |1 q" H  Z/ P
  284.                         int movecount;! z6 C8 ?" I  W& t4 p
  285.                         // 拖动的=开始拖的,并且 拖动的 不等于放下的0 G0 G% W0 g. ?7 _7 y& M+ X
  286.                         if ((dragPosition == startPosition)
    0 o5 O( z6 P/ R5 O( s! b  g
  287.                                         || (dragPosition != dropPosition)) {7 V0 I- V' S( B  P, D) m4 i0 M6 S
  288.                                 // 移需要移动的动ITEM数量( ?; _" R# s% f- ^6 U. |- }/ Z
  289.                                 movecount = dropPosition - dragPosition;
    + L7 i4 t+ A- d# A/ e) C
  290.                         } else {8 z) W8 J' N0 }& p- c
  291.                                 // 移需要移动的动ITEM数量为0
    0 B  Y4 N4 F3 L; ?$ B- I# @
  292.                                 movecount = 0;% e+ c+ j3 v" E7 s/ T
  293.                         }
    & x8 i# P) T0 o. c; s
  294.                         if (movecount == 0) {7 ^" j4 F, t% y% f3 F  r) V
  295.                                 return;
    5 v. }& B* g* T
  296.                         }+ ~, k% J& S7 g; [7 f

  297. ( f9 N  E  m1 }0 v( C; @# h- X
  298.                         int movecount_abs = Math.abs(movecount);
    $ B5 ^/ A6 v) A. N/ g

  299. % X5 [* ~# D+ L. H
  300.                         if (dPosition != dragPosition) {1 D- i( |0 r2 V$ V" Q
  301.                                 // dragGroup设置为不可见  J0 y7 A& H/ ]( t2 [
  302.                                 ViewGroup dragGroup = (ViewGroup) getChildAt(dragPosition);
    7 v' p* S7 ?+ @/ ^* d4 A
  303.                                 dragGroup.setVisibility(View.INVISIBLE);/ Q0 G; j! B  p7 ^' ?
  304.                                 float to_x = 1;// 当前下方positon
    6 X' g" D- A4 v- `
  305.                                 float to_y;// 当前下方右边positon9 {( S7 q- \6 l, c* J* d/ U; K# C
  306.                                 // x_vlaue移动的距离百分比(相对于自己长度的百分比)- |% v& v' v2 @
  307.                                 float x_vlaue = ((float) mHorizontalSpacing / (float) itemWidth) + 1.0f;
    # h. O% k$ \! k
  308.                                 // y_vlaue移动的距离百分比(相对于自己宽度的百分比)
    ( Z/ ]9 y- R! H  M
  309.                                 float y_vlaue = ((float) mVerticalSpacing / (float) itemHeight) + 1.0f;2 L& W/ q: k( J6 c7 ]
  310.                                 Log.d("x_vlaue", "x_vlaue = " + x_vlaue);) [- a* j: c3 P. @0 d$ ~/ G6 P
  311.                                 for (int i = 0; i < movecount_abs; i++) {' M- J1 d3 `  G  M2 y
  312.                                         to_x = x_vlaue;8 ^. t8 T  @" }* X0 x
  313.                                         to_y = y_vlaue;
    ' W: P: s, \/ N! ^
  314.                                         // 像左8 F! _- [0 R4 z. ~6 r
  315.                                         if (movecount > 0) {$ ]) u" \4 L/ @1 H8 c. Y! U
  316.                                                 // 判断是不是同一行的0 n+ e  Z- E$ x
  317.                                                 holdPosition = dragPosition + i + 1;
    # F* o+ I3 b7 }/ \3 T' g
  318.                                                 if (dragPosition / nColumns == holdPosition / nColumns) {" \, i+ L  w5 V7 Q6 r
  319.                                                         to_x = -x_vlaue;
    3 E5 v8 N, |" z0 i, H
  320.                                                         to_y = 0;
    ' o1 H$ o% d9 e9 }7 C. J: s
  321.                                                 } else if (holdPosition % 4 == 0) {
    # L/ [" U9 a$ G4 p0 Y/ A. l9 t
  322.                                                         to_x = 3 * x_vlaue;
    ; R% r, s- ?1 P  i, l" E
  323.                                                         to_y = -y_vlaue;
    9 S% K4 C( `  p  ~& r
  324.                                                 } else {" ?6 w8 L8 p4 M/ T
  325.                                                         to_x = -x_vlaue;
    5 a% X4 E* a& z, R
  326.                                                         to_y = 0;$ S; c) F9 k, L% D, R
  327.                                                 }
    1 G. @9 Y  q; t# i8 m" r) V
  328.                                         } else {  y3 i: W2 c% j2 T! m5 a
  329.                                                 // 向右,下移到上,右移到左3 z. P' m  p# H* n5 B  X3 M
  330.                                                 holdPosition = dragPosition - i - 1;8 }+ a# {" U$ @1 f: H
  331.                                                 if (dragPosition / nColumns == holdPosition / nColumns) {
    & _# b3 }+ L7 d$ ^; U
  332.                                                         to_x = x_vlaue;+ t9 S" Q) H3 w/ a: U
  333.                                                         to_y = 0;
      \; y, {, N4 N
  334.                                                 } else if ((holdPosition + 1) % 4 == 0) {  }' ?6 @/ O+ z( {5 ~% B) n
  335.                                                         to_x = -3 * x_vlaue;$ \) p: Y+ p& X
  336.                                                         to_y = y_vlaue;$ t! E( G0 J9 V( F( a6 y
  337.                                                 } else {. N# U+ A% r3 _( m% g
  338.                                                         to_x = x_vlaue;, @8 _' Q5 [" J+ c' X6 F2 [/ `  q
  339.                                                         to_y = 0;( {& _' E/ i; |! K- k* ?
  340.                                                 }. ~: H; T) U# [3 Y; ?! p
  341.                                         }' M) X+ T$ ?  v& g9 X& H6 G# j
  342.                                         ViewGroup moveViewGroup = (ViewGroup) getChildAt(holdPosition);4 Q: M% C: R- n# _2 [* `- r
  343.                                         Animation moveAnimation = getMoveAnimation(to_x, to_y);
    , z" v( x, e7 i/ \
  344.                                         moveViewGroup.startAnimation(moveAnimation);! E6 d9 E, C1 w- `
  345.                                         // 如果是最后一个移动的,那么设置他的最后个动画ID为LastAnimationID0 }- o; m6 s* p- [( q- x  X! ^# C* G
  346.                                         if (holdPosition == dropPosition) {* d; h, ^0 x3 X  U
  347.                                                 LastAnimationID = moveAnimation.toString();! ~: ?' O7 X( s. h) d5 [+ C
  348.                                         }. n9 M' S1 @, Z, s, P+ G
  349.                                         moveAnimation.setAnimationListener(new AnimationListener() {
    2 X5 b0 y7 \( k6 b9 C+ V$ T
  350. 2 e' d, s7 r. Y) [
  351.                                                 @Override/ U1 @" T5 G" h8 D0 r* x& c
  352.                                                 public void onAnimationStart(Animation animation) {. \) ^2 A6 u; O% l4 ?
  353.                                                         // TODO Auto-generated method stub  Q4 p/ H( Q8 T: F$ L. K
  354.                                                         isMoving = true;
    6 i+ D: K& I' I1 V+ f
  355.                                                 }& I  ]: J( V! S6 @
  356. $ Y+ O. I  u4 }2 G) Y, H; P
  357.                                                 @Override
    & o; x7 F5 D: u
  358.                                                 public void onAnimationRepeat(Animation animation) {
    8 s4 s. q; S1 u5 O7 _0 f
  359.                                                         // TODO Auto-generated method stub6 m* W6 N" ^6 z  g( `
  360. : i9 Z$ `* z% ?% e+ u0 m" S# B! @% u
  361.                                                 }# T) H8 d; W: x

  362. / ^) g% w3 S* p/ A/ `% Z
  363.                                                 @Override1 I4 F; A( c) \" N
  364.                                                 public void onAnimationEnd(Animation animation) {. Z2 o' Y5 `" L+ L# e
  365.                                                         // TODO Auto-generated method stub
    * d: s2 t) @. K/ S  P2 n
  366.                                                         // 如果为最后个动画结束,那执行下面的方法
    " I) ]' ~# C3 u3 I
  367.                                                         if (animation.toString().equalsIgnoreCase(
    " U( f: k  f0 Z1 G
  368.                                                                         LastAnimationID)) {( I2 j& [. S$ W0 d  ]% ?4 j
  369.                                                                 DragAdapter mDragAdapter = (DragAdapter) getAdapter();
    # k: T: m2 h3 _9 U6 W
  370.                                                                 mDragAdapter.exchange(startPosition,# a" I) p) W" J% Y0 W
  371.                                                                                 dropPosition);1 `0 a3 K- b' p5 j
  372.                                                                 startPosition = dropPosition;; z4 z* Q7 W. y1 y# d1 g
  373.                                                                 dragPosition = dropPosition;
    $ Z- Q& u  S- `1 |
  374.                                                                 isMoving = false;
    7 F9 A! g, z7 @6 H* I0 P
  375.                                                         }; q8 E6 w* g& d( K. N
  376.                                                 }6 u* t! }; V6 n3 ^1 G, s
  377.                                         });
    2 t" }: `0 r0 i0 B' ^- j8 T
  378.                                 }7 Z" J0 p3 r) I% q9 U
  379.                         }  B& z2 ~( P; N4 u' _, E
  380.                 }
    0 n3 ^5 T+ E! a9 W* X
  381.         }3 e6 X: _* k$ S" {2 z. r8 L" N0 W
  382. }
复制代码
数据库SQLHelper文件. I- g! s8 m$ }5 @* ^
  1. public class SQLHelper extends SQLiteOpenHelper {5 {" I" i" l6 T6 R: M% H" U4 O# H0 C
  2.         public static final String DB_NAME = "database.db";// 数据库名称
    ; f- \( F- o9 S. S9 K# u
  3.         public static final int VERSION = 1;! O4 U% F2 V+ q+ t; f
  4.         / T! I/ X/ g% L1 K0 p. U
  5.         public static final String TABLE_CHANNEL = "channel";//数据表 * M! s4 a; I* F+ |8 C# H

  6. 8 z! E1 c5 [5 q) V8 h: C
  7.         public static final String ID = "id";//
    + P9 Q5 V0 S  i7 _2 X, [: V5 K
  8.         public static final String NAME = "name";* m% ^  t6 a2 M1 k% a7 _: w6 h
  9.         public static final String ORDERID = "orderId";: f8 H  E5 z9 G! F$ B; k
  10.         public static final String SELECTED = "selected";
    + P: u7 E$ v3 m, [* t) K
  11.         private Context context;
    ' ^) g8 A2 O' P* {( L2 E% X; W7 x) Q
  12.         public SQLHelper(Context context) {  {0 E$ L% z' h
  13.                 super(context, DB_NAME, null, VERSION);
    4 ?9 a) U: G* t2 j$ l
  14.                 this.context = context;' Z* v& ^9 L9 g# G$ Z  m* m4 ^1 t
  15.         }7 R& O3 e5 _, o1 x0 L; M
  16. 3 r, F3 G3 i) @1 _1 c
  17.         public Context getContext(){
    & K$ X  }- X4 E/ P7 O# i& U
  18.                 return context;) w6 \5 h6 k; ?. H- i" U
  19.         }3 m9 j. D3 J8 i- n- c: `3 D
  20.         6 w# J9 y3 W2 @
  21.         @Override  w! e( k' T: ~) u
  22.         public void onCreate(SQLiteDatabase db) {
    ' f$ }2 c4 e4 b" h2 z
  23.                 // TODO 创建数据库后,对数据库的操作
    % H- H5 a+ i( ~, @* `8 `2 g2 b+ }" U
  24.                 String sql = "create table if not exists "+TABLE_CHANNEL +
    8 H, x3 W+ G9 h. O1 T
  25.                                 "(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
    ' Y  z; u/ [* U  E, O
  26.                                 ID + " INTEGER , " +
    ) L( G2 e( w) D
  27.                                 NAME + " TEXT , " +
    : _+ z7 ]" ?+ O5 X, V
  28.                                 ORDERID + " INTEGER , " +
    + q8 p1 K( w7 F$ P( C9 q
  29.                                 SELECTED + " SELECTED)";4 i4 O& `  }4 |* R- M: X
  30.                 db.execSQL(sql);& K+ e& w3 S5 ]/ W8 a" U  X
  31.         }$ Z5 v! S' p; E
  32. $ m$ ?; [. f* k: w
  33.         @Override: D4 c5 ^" F# A
  34.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {: ?7 w3 ~( `$ }* O$ C
  35.                 // TODO 更改数据库版本的操作0 C$ O  e0 [: e0 P% ~8 J; T
  36.                 onCreate(db);
    $ l* S& j9 O- G+ c& L
  37.         }
    ( r6 R7 S1 ]* @, L, C
  38. & \" |9 V$ C. X
  39. }
    . F' W2 C) Y& ~# r7 D
复制代码
注:本DEMO中,加入了长按震动,所以在权限里面记得加上“, V' A3 N& k4 @1 B/ d' H9 l  b
  1.     <!-- 在SDCard中创建与删除文件权限 -->3 p# O8 W- z/ w
  2.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />$ x# B8 V* f4 g
  3.     <!-- 往SDCard写入数据权限 -->! G: r2 ]4 x$ S+ y
  4.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    1 r' r1 H5 j. {4 a6 X8 ]# [6 [
  5.     <!-- 震动权限 -->
    " l! ?- O3 D6 o" J) C1 z$ n/ V5 ~
  6.     <uses-permission android:name="android.permission.VIBRATE"/>
复制代码

* ~# x8 m; O, C, \) a4 d六、源码下载源码DEMO下载地址如下:% X5 g+ i! m0 Y$ B  F2 x/ A
游客,如果您要查看本帖隐藏内容请回复

( m2 r- _1 m: e) x3 \( F( m: g8 G
$ p* y% Z( Y# z- t3 Q& ^
# q4 J$ B; S0 `
发表于 2014-8-9 18:03 | 显示全部楼层
ttedgdfgdfg
发表于 2014-9-5 10:03 | 显示全部楼层
谢谢分享                    
发表于 2014-9-30 10:07 | 显示全部楼层
; x5 H) V. @; k# @" t+ H8 @
谢谢分享   
发表于 2014-10-27 21:58 | 显示全部楼层
必须支持楼主
发表于 2014-11-3 16:40 | 显示全部楼层
谢谢楼主,,分享,,下载看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

© 2001-2014Comsenz Inc.

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