http://blog.csdn.net/daditao/article/details/27668489

http://blog.csdn.net/daditao/article/details/27668489
http://blog.csdn.net/daditao/article/details/27668489
http://blog.csdn.net/daditao/article/details/27668489
http://blog.csdn.net/daditao/article/details/27668489



Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO

分类:android 46人阅读 评论(0) 收藏 举报

目录(?)[+]

http://blog.csdn.net/vipzjyno1/article/details/25005851

距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二)

相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下。完善的功能一个一个全部实现后,就放整个源码。开发的进度就是按照一个一个功能的思路走的,所以开发一个小的功能,如果有用,就写一个专门的博客以便有人用到独立的功能可以方便使用。

这次实现的功能是很多新闻阅读器(网易,今日头条,360新闻等)以及腾讯视频等里面都会出现的频道管理功能。


下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看)



一、开发心里历程

刚开始接触这个的时候,不知道要如何实现,去网上翻了一大堆资料,懂了个大概,就是目前可以找到的都是拖拽的时候,不带移动动画的,和线上的客户端交互效果相差甚远,在反反复复的尝试查看相关东西,大致的做了出来,目前在模拟器上似乎有一点小BUG,真机测试没有问题,就先放上来,如果发现问题在修改优化。代码反面,没有好好的修改调整,可能会有点乱,请见谅哈。


二、开发前的准备

1.了解重写View的相关知识,并且知道GridView的一些内部方法,如:怎么通过触摸的坐标获取对应的position等(这里我采用的是继承GridView控件)

2.了解屏幕触摸动作传递原理 这里我以前转载的一篇或许会有帮助:Android事件分发机制完全解析,带你从源码的角度彻底理解(全)

3.了解位移动画Animation,本DEMO中主要用到:TranslateAnimation 平移动画

4.了解WindowManager的窗口机制,这里的item拖拽等都要设计到这个。

5.了解SQLiteDatabase 以及SQLiteOpenHelper等数据库操作相关的类,本DEMO中主要用到数据库进行存储频道信息,如果你要用文档进行存储读取也可以。


三、开发思路

1. 获取数据库中频道的列表,如果为空,赋予默认列表,并存入数据库,之后通过对应的适配器赋给对应的GridView


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

DragGrid 用于显示我的频道,带有长按拖拽效果

OtherGridView用于显示更多频道,不带推拽效果

注:由于屏幕大小不一定,外层使用ScrollView,所以2者都要重写计算高度


3. 点击2个GridView的时候,根据点击的Item对应的position,获取position对应的view,进行创建一层移动的动画层

起始位置:点击的positiongetLocationInWindow()获取。终点位置:另一个GridView的最后个ITEM 的position+ 1的位置。

并赋予移动动画,等动画结束后对2者对应的频道列表进行数据的remove和add操作。


4. 设置点击和拖动的限制条件,如 推荐 这个ITEM是不允许用户操作的。


5. 拖动的DragGrid的操作:

(1)长按获取长按的ITEM的position -- dragPosition以及对应的view ,手指触摸屏幕的时候,调用onInterceptTouchEvent来获取MotionEvent.ACTION_DOWN事件,获取对应的数据。由于这里是继承了GridView,所以长按时间可以通过setOnItemLongClickListener监听来执行,或则你也可以通过计算点击时间来监听是否长按。

(2)通过onTouchEvent(MotionEvent ev)来监听手指的移动和抬起动作。当它移动到 其它的item下面,并且下方的item对应的position 不等于dragPosition,进行数据交换,并且2者之间的所有item进行移动动画,动画结束后,数据更替刷新界面。

(3)抬起手后,清除掉拖动时候创建的view,让GridView中的数据显示。


6. 退出时候,将改变后的频道列表存入数据库。


四、流程图

下面是大体的流程图:




五、核心代码

点击进行添加删除: [java] view plain copy
  1. /**GRIDVIEW对应的ITEM点击监听接口*/
  2. @Override
  3. publicvoidonItemClick(AdapterView<?>parent,finalViewview,finalintposition,longid){
  4. //如果点击的时候,之前动画还没结束,那么就让点击事件无效
  5. if(isMove){
  6. return;
  7. }
  8. switch(parent.getId()){
  9. caseR.id.userGridView:
  10. //position为0,1的不可以进行任何操作
  11. if(position!=0&&position!=1){
  12. finalImageViewmoveImageView=getView(view);
  13. if(moveImageView!=null){
  14. TextViewnewTextView=(TextView)view.findViewById(R.id.text_item);
  15. finalint[]startLocation=newint[2];
  16. newTextView.getLocationInWindow(startLocation);
  17. finalChannelItemchannel=((DragAdapter)parent.getAdapter()).getItem(position);//获取点击的频道内容
  18. otherAdapter.setVisible(false);
  19. //添加到最后一个
  20. otherAdapter.addItem(channel);
  21. newHandler().postDelayed(newRunnable(){
  22. publicvoidrun(){
  23. try{
  24. int[]endLocation=newint[2];
  25. //获取终点的坐标
  26. otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
  27. MoveAnim(moveImageView,startLocation,endLocation,channel,userGridView);
  28. userAdapter.setRemove(position);
  29. }catch(ExceptionlocalException){
  30. }
  31. }
  32. },50L);
  33. }
  34. }
  35. break;
  36. caseR.id.otherGridView:
  37. finalImageViewmoveImageView=getView(view);
  38. if(moveImageView!=null){
  39. TextViewnewTextView=(TextView)view.findViewById(R.id.text_item);
  40. finalint[]startLocation=newint[2];
  41. newTextView.getLocationInWindow(startLocation);
  42. finalChannelItemchannel=((OtherAdapter)parent.getAdapter()).getItem(position);
  43. userAdapter.setVisible(false);
  44. //添加到最后一个
  45. userAdapter.addItem(channel);
  46. newHandler().postDelayed(newRunnable(){
  47. publicvoidrun(){
  48. try{
  49. int[]endLocation=newint[2];
  50. //获取终点的坐标
  51. userGridView.getChildAt(userGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
  52. MoveAnim(moveImageView,startLocation,endLocation,channel,otherGridView);
  53. otherAdapter.setRemove(position);
  54. }catch(ExceptionlocalException){
  55. }
  56. }
  57. },50L);
  58. }
  59. break;
  60. default:
  61. break;
  62. }
  63. }


移动动画: [java] view plain copy
  1. <spanstyle="font-size:14px;">privatevoidMoveAnim(ViewmoveView,int[]startLocation,int[]endLocation,finalChannelItemmoveChannel,
  2. finalGridViewclickGridView){
  3. int[]initLocation=newint[2];
  4. //获取传递过来的VIEW的坐标
  5. moveView.getLocationInWindow(initLocation);
  6. //得到要移动的VIEW,并放入对应的容器中
  7. finalViewGroupmoveViewGroup=getMoveViewGroup();
  8. finalViewmMoveView=getMoveView(moveViewGroup,moveView,initLocation);
  9. //创建移动动画
  10. TranslateAnimationmoveAnimation=newTranslateAnimation(
  11. startLocation[0],endLocation[0],startLocation[1],
  12. endLocation[1]);
  13. moveAnimation.setDuration(300L);//动画时间
  14. //动画配置
  15. AnimationSetmoveAnimationSet=newAnimationSet(true);
  16. moveAnimationSet.setFillAfter(false);//动画效果执行完毕后,View对象不保留在终止的位置
  17. moveAnimationSet.addAnimation(moveAnimation);
  18. mMoveView.startAnimation(moveAnimationSet);
  19. moveAnimationSet.setAnimationListener(newAnimationListener(){
  20. @Override
  21. publicvoidonAnimationStart(Animationanimation){
  22. isMove=true;
  23. }
  24. @Override
  25. publicvoidonAnimationRepeat(Animationanimation){
  26. }
  27. @Override
  28. publicvoidonAnimationEnd(Animationanimation){
  29. moveViewGroup.removeView(mMoveView);
  30. //instanceof方法判断2边实例是不是一样,判断点击的是DragGrid还是OtherGridView
  31. if(clickGridViewinstanceofDragGrid){
  32. otherAdapter.setVisible(true);
  33. otherAdapter.notifyDataSetChanged();
  34. userAdapter.remove();
  35. }else{
  36. userAdapter.setVisible(true);
  37. userAdapter.notifyDataSetChanged();
  38. otherAdapter.remove();
  39. }
  40. isMove=false;
  41. }
  42. });
  43. }</span>

可拖拽的DragGrid代码:
[java] view plain copy
  1. publicclassDragGridextendsGridView{
  2. /**点击时候的X位置*/
  3. publicintdownX;
  4. /**点击时候的Y位置*/
  5. publicintdownY;
  6. /**点击时候对应整个界面的X位置*/
  7. publicintwindowX;
  8. /**点击时候对应整个界面的Y位置*/
  9. publicintwindowY;
  10. /**屏幕上的X*/
  11. privateintwin_view_x;
  12. /**屏幕上的Y*/
  13. privateintwin_view_y;
  14. /**拖动的里x的距离*/
  15. intdragOffsetX;
  16. /**拖动的里Y的距离*/
  17. intdragOffsetY;
  18. /**长按时候对应postion*/
  19. publicintdragPosition;
  20. /**Up后对应的ITEM的Position*/
  21. privateintdropPosition;
  22. /**开始拖动的ITEM的Position*/
  23. privateintstartPosition;
  24. /**item高*/
  25. privateintitemHeight;
  26. /**item宽*/
  27. privateintitemWidth;
  28. /**拖动的时候对应ITEM的VIEW*/
  29. privateViewdragImageView=null;
  30. /**长按的时候ITEM的VIEW*/
  31. privateViewGroupdragItemView=null;
  32. /**WindowManager管理器*/
  33. privateWindowManagerwindowManager=null;
  34. /***/
  35. privateWindowManager.LayoutParamswindowParams=null;
  36. /**item总量*/
  37. privateintitemTotalCount;
  38. /**一行的ITEM数量*/
  39. privateintnColumns=4;
  40. /**行数*/
  41. privateintnRows;
  42. /**剩余部分*/
  43. privateintRemainder;
  44. /**是否在移动*/
  45. privatebooleanisMoving=false;
  46. /***/
  47. privateintholdPosition;
  48. /**拖动的时候放大的倍数*/
  49. privatedoubledragScale=1.2D;
  50. /**震动器*/
  51. privateVibratormVibrator;
  52. /**每个ITEM之间的水平间距*/
  53. privateintmHorizontalSpacing=15;
  54. /**每个ITEM之间的竖直间距*/
  55. privateintmVerticalSpacing=15;
  56. /*移动时候最后个动画的ID*/
  57. privateStringLastAnimationID;
  58. publicDragGrid(Contextcontext){
  59. super(context);
  60. init(context);
  61. }
  62. publicDragGrid(Contextcontext,AttributeSetattrs,intdefStyle){
  63. super(context,attrs,defStyle);
  64. init(context);
  65. }
  66. publicDragGrid(Contextcontext,AttributeSetattrs){
  67. super(context,attrs);
  68. init(context);
  69. }
  70. publicvoidinit(Contextcontext){
  71. mVibrator=(Vibrator)context
  72. .getSystemService(Context.VIBRATOR_SERVICE);
  73. //将布局文件中设置的间距dip转为px
  74. mHorizontalSpacing=DataTools.dip2px(context,mHorizontalSpacing);
  75. }
  76. @Override
  77. publicbooleanonInterceptTouchEvent(MotionEventev){
  78. //TODOAuto-generatedmethodstub
  79. if(ev.getAction()==MotionEvent.ACTION_DOWN){
  80. downX=(int)ev.getX();
  81. downY=(int)ev.getY();
  82. windowX=(int)ev.getX();
  83. windowY=(int)ev.getY();
  84. setOnItemClickListener(ev);
  85. }
  86. returnsuper.onInterceptTouchEvent(ev);
  87. }
  88. @Override
  89. publicbooleanonTouchEvent(MotionEventev){
  90. //TODOAuto-generatedmethodstub
  91. booleanbool=true;
  92. if(dragImageView!=null
  93. &&dragPosition!=AdapterView.INVALID_POSITION){
  94. //移动时候的对应x,y位置
  95. bool=super.onTouchEvent(ev);
  96. intx=(int)ev.getX();
  97. inty=(int)ev.getY();
  98. switch(ev.getAction()){
  99. caseMotionEvent.ACTION_DOWN:
  100. downX=(int)ev.getX();
  101. windowX=(int)ev.getX();
  102. downY=(int)ev.getY();
  103. windowY=(int)ev.getY();
  104. break;
  105. caseMotionEvent.ACTION_MOVE:
  106. onDrag(x,y,(int)ev.getRawX(),(int)ev.getRawY());
  107. if(!isMoving){
  108. OnMove(x,y);
  109. }
  110. if(pointToPosition(x,y)!=AdapterView.INVALID_POSITION){
  111. break;
  112. }
  113. break;
  114. caseMotionEvent.ACTION_UP:
  115. stopDrag();
  116. onDrop(x,y);
  117. requestDisallowInterceptTouchEvent(false);
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. returnsuper.onTouchEvent(ev);
  124. }
  125. /**在拖动的情况*/
  126. privatevoidonDrag(intx,inty,intrawx,intrawy){
  127. if(dragImageView!=null){
  128. windowParams.alpha=0.6f;
  129. windowParams.x=rawx-win_view_x;
  130. windowParams.y=rawy-win_view_y;
  131. windowManager.updateViewLayout(dragImageView,windowParams);
  132. }
  133. }
  134. /**在松手下放的情况*/
  135. privatevoidonDrop(intx,inty){
  136. //根据拖动到的x,y坐标获取拖动位置下方的ITEM对应的POSTION
  137. inttempPostion=pointToPosition(x,y);
  138. dropPosition=tempPostion;
  139. DragAdaptermDragAdapter=(DragAdapter)getAdapter();
  140. //显示刚拖动的ITEM
  141. mDragAdapter.setShowDropItem(true);
  142. //刷新适配器,让对应的ITEM显示
  143. mDragAdapter.notifyDataSetChanged();
  144. }
  145. /**
  146. *长按点击监听
  147. *@paramev
  148. */
  149. publicvoidsetOnItemClickListener(finalMotionEventev){
  150. setOnItemLongClickListener(newOnItemLongClickListener(){
  151. @Override
  152. publicbooleanonItemLongClick(AdapterView<?>parent,Viewview,
  153. intposition,longid){
  154. intx=(int)ev.getX();//长安事件的X位置
  155. inty=(int)ev.getY();//长安事件的y位置
  156. startPosition=position;//第一次点击的postion
  157. dragPosition=position;
  158. if(startPosition<=1){
  159. returnfalse;
  160. }
  161. ViewGroupdragViewGroup=(ViewGroup)getChildAt(dragPosition
  162. -getFirstVisiblePosition());
  163. TextViewdragTextView=(TextView)dragViewGroup
  164. .findViewById(R.id.text_item);
  165. dragTextView.setSelected(true);
  166. dragTextView.setEnabled(false);
  167. itemHeight=dragViewGroup.getHeight();
  168. itemWidth=dragViewGroup.getWidth();
  169. itemTotalCount=DragGrid.this.getCount();
  170. introw=itemTotalCount/nColumns;//算出行数
  171. Remainder=(itemTotalCount%nColumns);//算出最后一行多余的数量
  172. if(Remainder!=0){
  173. nRows=row+1;
  174. }else{
  175. nRows=row;
  176. }
  177. //如果特殊的这个不等于拖动的那个,并且不等于-1
  178. if(dragPosition!=AdapterView.INVALID_POSITION){
  179. //释放的资源使用的绘图缓存。如果你调用buildDrawingCache()手动没有调用setDrawingCacheEnabled(真正的),你应该清理缓存使用这种方法。
  180. win_view_x=windowX-dragViewGroup.getLeft();//VIEW相对自己的X,半斤
  181. win_view_y=windowY-dragViewGroup.getTop();//VIEW相对自己的y,半斤
  182. dragOffsetX=(int)(ev.getRawX()-x);//手指在屏幕的上X位置-手指在控件中的位置就是距离最左边的距离
  183. dragOffsetY=(int)(ev.getRawY()-y);//手指在屏幕的上y位置-手指在控件中的位置就是距离最上边的距离
  184. dragItemView=dragViewGroup;
  185. dragViewGroup.destroyDrawingCache();
  186. dragViewGroup.setDrawingCacheEnabled(true);
  187. BitmapdragBitmap=Bitmap.createBitmap(dragViewGroup
  188. .getDrawingCache());
  189. mVibrator.vibrate(50);//设置震动时间
  190. startDrag(dragBitmap,(int)ev.getRawX(),
  191. (int)ev.getRawY());
  192. hideDropItem();
  193. dragViewGroup.setVisibility(View.INVISIBLE);
  194. isMoving=false;
  195. requestDisallowInterceptTouchEvent(true);
  196. returntrue;
  197. }
  198. returnfalse;
  199. }
  200. });
  201. }
  202. publicvoidstartDrag(BitmapdragBitmap,intx,inty){
  203. stopDrag();
  204. windowParams=newWindowManager.LayoutParams();//获取WINDOW界面的
  205. //Gravity.TOP|Gravity.LEFT;这个必须加
  206. windowParams.gravity=Gravity.TOP|Gravity.LEFT;
  207. //得到preview左上角相对于屏幕的坐标
  208. windowParams.x=x-win_view_x;
  209. windowParams.y=y-win_view_y;
  210. //设置拖拽item的宽和高
  211. windowParams.width=(int)(dragScale*dragBitmap.getWidth());//放大dragScale倍,可以设置拖动后的倍数
  212. windowParams.height=(int)(dragScale*dragBitmap.getHeight());//放大dragScale倍,可以设置拖动后的倍数
  213. this.windowParams.flags=WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
  214. |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
  215. |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
  216. |WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
  217. this.windowParams.format=PixelFormat.TRANSLUCENT;
  218. this.windowParams.windowAnimations=0;
  219. ImageViewiv=newImageView(getContext());
  220. iv.setImageBitmap(dragBitmap);
  221. windowManager=(WindowManager)getContext().getSystemService(
  222. Context.WINDOW_SERVICE);//"window"
  223. windowManager.addView(iv,windowParams);
  224. dragImageView=iv;
  225. }
  226. /**停止拖动,释放并初始化*/
  227. privatevoidstopDrag(){
  228. if(dragImageView!=null){
  229. windowManager.removeView(dragImageView);
  230. dragImageView=null;
  231. }
  232. }
  233. /**在ScrollView内,所以要进行计算高度*/
  234. @Override
  235. publicvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
  236. intexpandSpec=MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,
  237. MeasureSpec.AT_MOST);
  238. super.onMeasure(widthMeasureSpec,expandSpec);
  239. }
  240. /**隐藏放下的ITEM*/
  241. privatevoidhideDropItem(){
  242. ((DragAdapter)getAdapter()).setShowDropItem(false);
  243. }
  244. /**获取移动动画*/
  245. publicAnimationgetMoveAnimation(floattoXValue,floattoYValue){
  246. TranslateAnimationmTranslateAnimation=newTranslateAnimation(
  247. Animation.RELATIVE_TO_SELF,0.0F,Animation.RELATIVE_TO_SELF,
  248. toXValue,Animation.RELATIVE_TO_SELF,0.0F,
  249. Animation.RELATIVE_TO_SELF,toYValue);//当前位置移动到指定位置
  250. mTranslateAnimation.setFillAfter(true);//设置一个动画效果执行完毕后,View对象保留在终止的位置。
  251. mTranslateAnimation.setDuration(300L);
  252. returnmTranslateAnimation;
  253. }
  254. /**移动的时候触发*/
  255. publicvoidOnMove(intx,inty){
  256. //拖动的VIEW下方的POSTION
  257. intdPosition=pointToPosition(x,y);
  258. //判断下方的POSTION是否是最开始2个不能拖动的
  259. if(dPosition>1){
  260. if((dPosition==-1)||(dPosition==dragPosition)){
  261. return;
  262. }
  263. dropPosition=dPosition;
  264. if(dragPosition!=startPosition){
  265. dragPosition=startPosition;
  266. }
  267. intmovecount;
  268. //拖动的=开始拖的,并且拖动的不等于放下的
  269. if((dragPosition==startPosition)
  270. ||(dragPosition!=dropPosition)){
  271. //移需要移动的动ITEM数量
  272. movecount=dropPosition-dragPosition;
  273. }else{
  274. //移需要移动的动ITEM数量为0
  275. movecount=0;
  276. }
  277. if(movecount==0){
  278. return;
  279. }
  280. intmovecount_abs=Math.abs(movecount);
  281. if(dPosition!=dragPosition){
  282. //dragGroup设置为不可见
  283. ViewGroupdragGroup=(ViewGroup)getChildAt(dragPosition);
  284. dragGroup.setVisibility(View.INVISIBLE);
  285. floatto_x=1;//当前下方positon
  286. floatto_y;//当前下方右边positon
  287. //x_vlaue移动的距离百分比(相对于自己长度的百分比)
  288. floatx_vlaue=((float)mHorizontalSpacing/(float)itemWidth)+1.0f;
  289. //y_vlaue移动的距离百分比(相对于自己宽度的百分比)
  290. floaty_vlaue=((float)mVerticalSpacing/(float)itemHeight)+1.0f;
  291. Log.d("x_vlaue","x_vlaue="+x_vlaue);
  292. for(inti=0;i<movecount_abs;i++){
  293. to_x=x_vlaue;
  294. to_y=y_vlaue;
  295. //像左
  296. if(movecount>0){
  297. //判断是不是同一行的
  298. holdPosition=dragPosition+i+1;
  299. if(dragPosition/nColumns==holdPosition/nColumns){
  300. to_x=-x_vlaue;
  301. to_y=0;
  302. }elseif(holdPosition%4==0){
  303. to_x=3*x_vlaue;
  304. to_y=-y_vlaue;
  305. }else{
  306. to_x=-x_vlaue;
  307. to_y=0;
  308. }
  309. }else{
  310. //向右,下移到上,右移到左
  311. holdPosition=dragPosition-i-1;
  312. if(dragPosition/nColumns==holdPosition/nColumns){
  313. to_x=x_vlaue;
  314. to_y=0;
  315. }elseif((holdPosition+1)%4==0){
  316. to_x=-3*x_vlaue;
  317. to_y=y_vlaue;
  318. }else{
  319. to_x=x_vlaue;
  320. to_y=0;
  321. }
  322. }
  323. ViewGroupmoveViewGroup=(ViewGroup)getChildAt(holdPosition);
  324. AnimationmoveAnimation=getMoveAnimation(to_x,to_y);
  325. moveViewGroup.startAnimation(moveAnimation);
  326. //如果是最后一个移动的,那么设置他的最后个动画ID为LastAnimationID
  327. if(holdPosition==dropPosition){
  328. LastAnimationID=moveAnimation.toString();
  329. }
  330. moveAnimation.setAnimationListener(newAnimationListener(){
  331. @Override
  332. publicvoidonAnimationStart(Animationanimation){
  333. //TODOAuto-generatedmethodstub
  334. isMoving=true;
  335. }
  336. @Override
  337. publicvoidonAnimationRepeat(Animationanimation){
  338. //TODOAuto-generatedmethodstub
  339. }
  340. @Override
  341. publicvoidonAnimationEnd(Animationanimation){
  342. //TODOAuto-generatedmethodstub
  343. //如果为最后个动画结束,那执行下面的方法
  344. if(animation.toString().equalsIgnoreCase(
  345. LastAnimationID)){
  346. DragAdaptermDragAdapter=(DragAdapter)getAdapter();
  347. mDragAdapter.exchange(startPosition,
  348. dropPosition);
  349. startPosition=dropPosition;
  350. dragPosition=dropPosition;
  351. isMoving=false;
  352. }
  353. }
  354. });
  355. }
  356. }
  357. }
  358. }
  359. }

数据库SQLHelper文件 [java] view plain copy
  1. publicclassSQLHelperextendsSQLiteOpenHelper{
  2. publicstaticfinalStringDB_NAME="database.db";//数据库名称
  3. publicstaticfinalintVERSION=1;
  4. publicstaticfinalStringTABLE_CHANNEL="channel";//数据表
  5. publicstaticfinalStringID="id";//
  6. publicstaticfinalStringNAME="name";
  7. publicstaticfinalStringORDERID="orderId";
  8. publicstaticfinalStringSELECTED="selected";
  9. privateContextcontext;
  10. publicSQLHelper(Contextcontext){
  11. super(context,DB_NAME,null,VERSION);
  12. this.context=context;
  13. }
  14. publicContextgetContext(){
  15. returncontext;
  16. }
  17. @Override
  18. publicvoidonCreate(SQLiteDatabasedb){
  19. //TODO创建数据库后,对数据库的操作
  20. Stringsql="createtableifnotexists"+TABLE_CHANNEL+
  21. "(_idINTEGERPRIMARYKEYAUTOINCREMENT,"+
  22. ID+"INTEGER,"+
  23. NAME+"TEXT,"+
  24. ORDERID+"INTEGER,"+
  25. SELECTED+"SELECTED)";
  26. db.execSQL(sql);
  27. }
  28. @Override
  29. publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
  30. //TODO更改数据库版本的操作
  31. onCreate(db);
  32. }
  33. }

注:本DEMO中,加入了长按震动,所以在权限里面记得加上“ [java] view plain copy
  1. <!--在SDCard中创建与删除文件权限-->
  2. <uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  3. <!--往SDCard写入数据权限-->
  4. <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  5. <!--震动权限-->
  6. <uses-permissionandroid:name="android.permission.VIBRATE"/>


六、源码下载

源码DEMO下载地址如下:下载地址




http://blog.csdn.net/daditao/article/details/27668489 http://blog.csdn.net/daditao/article/details/27668489 http://blog.csdn.net/daditao/article/details/27668489

更多相关文章

  1. android 学习使用Activity转场动画及shareElement
  2. Android(安卓)Animation总结
  3. Android属性动画property animation
  4. 使用系统资源的引用总结以及收到短信后给一个notification提示
  5. 33、多线程断点下载的实现&界面的更新
  6. Android(安卓)获取控件相对于屏幕位置
  7. android googleMap使用并在指定的位置上标注
  8. 使用最新版AndroidStudio2.0进行NDK开发并且链接第三方so库
  9. Android的Face++Demo错误1302

随机推荐

  1. android与HTML5相结合实现的省市县三级联
  2. 2014-7-23 Android ImageViwe自适应屏幕
  3. 运行Android程序时,出现提示:No compatibl
  4. Android NDK带来了什么
  5. android内核编译方法[转贴]
  6. Android 程序员指南 PDF下载
  7. android 应用自身检测版本并下载
  8. android应用 小试牛刀 开发自己的应用程
  9. 屏幕切换时Activity重启问题
  10. 利用android studio制作简易的计算器