Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果

摘要:
看到正点闹钟上的设置时间的滑动效果非常好看,自己就想做一个那样的,在网上就开始搜资料了,看到网上有的齿轮效果的代码非常多,也非常难懂,我就决定自己研究一下,现在我就把我的研究成果分享给大家。

看到正点闹钟上的设置时间的滑动效果非常好看,自己就想做一个那样的,在网上就开始搜资料了,看到网上有的齿轮效果的代码非常多,也非常难懂,我就决定自己研究一下,现在我就把我的研究成果分享给大家。我研究的这个效果出来了,而且代码也非常简单,通俗易懂。效果图如下:

Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果第1张

首先是MainActivity的布局文件,这个布局文件非常简单,就是一个Button:activity_main.xml文件,代码如下:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/ll_timeset"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="#ffffff"
  7. android:orientation="vertical">
  8. <Button
  9. android:id="@+id/btn"
  10. android:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. android:gravity="center"
  13. android:text="时间设置"
  14. android:textSize="24sp"/>
  15. </LinearLayout>

紧接着就是MainActivity的代码,代码如下:
  1. packagenet.loonggg.test;
  2. importnet.loonggg.view.CustomerDateDialog;
  3. importnet.loonggg.view.CustomerDateDialog.DateDialogListener;
  4. importandroid.app.Activity;
  5. importandroid.os.Bundle;
  6. importandroid.text.format.DateFormat;
  7. importandroid.view.View;
  8. importandroid.view.Window;
  9. importandroid.widget.Button;
  10. importandroid.widget.Toast;
  11. publicclassMainActivityextendsActivity{
  12. privateinth,m;
  13. privateCustomerDateDialogdialog;
  14. privateButtonbtn;
  15. @Override
  16. protectedvoidonCreate(BundlesavedInstanceState){
  17. super.onCreate(savedInstanceState);
  18. requestWindowFeature(Window.FEATURE_NO_TITLE);
  19. setContentView(R.layout.activity_main);
  20. btn=(Button)findViewById(R.id.btn);
  21. btn.setOnClickListener(newView.OnClickListener(){
  22. @Override
  23. publicvoidonClick(Viewv){
  24. Stringdatetime=DateFormat.format("kk:mm",
  25. System.currentTimeMillis()).toString();
  26. String[]strs=datetime.split(":");
  27. h=Integer.parseInt(strs[0]);
  28. m=Integer.parseInt(strs[1]);
  29. dialog=newCustomerDateDialog(MainActivity.this,h,m);
  30. dialog.show();
  31. dialog.setOnDateDialogListener(newDateDialogListener(){
  32. @Override
  33. publicvoidgetDate(){
  34. Toast.makeText(
  35. MainActivity.this,
  36. "时间是:"+dialog.getSettingHour()+"点"
  37. +dialog.getSettingMinute()+"分",
  38. Toast.LENGTH_LONG).show();
  39. }
  40. });
  41. }
  42. });
  43. }
  44. }

再就是我自定义了一个时钟的Dialog,自定义Dialog也非常简单,自己可以学一下,这方面网上的资料非常多。现在我把我自定义时钟的Dialog的代码分享一下,代码如下:
  1. packagenet.loonggg.view;
  2. importnet.loonggg.test.R;
  3. importandroid.annotation.SuppressLint;
  4. importandroid.app.Dialog;
  5. importandroid.content.Context;
  6. importandroid.os.Bundle;
  7. importandroid.os.Handler;
  8. importandroid.view.LayoutInflater;
  9. importandroid.view.MotionEvent;
  10. importandroid.view.View;
  11. importandroid.view.View.OnTouchListener;
  12. importandroid.view.ViewTreeObserver;
  13. importandroid.view.ViewTreeObserver.OnGlobalLayoutListener;
  14. importandroid.widget.Button;
  15. importandroid.widget.LinearLayout;
  16. importandroid.widget.ScrollView;
  17. importandroid.widget.TextView;
  18. @SuppressLint("HandlerLeak")
  19. publicclassCustomerDateDialogextendsDialog{
  20. privateViewcustomView;
  21. privateButtonsetBtn;
  22. privateButtoncancleBtn;
  23. privateTextViewarrow_up;
  24. privateTextViewtv01,tv02;
  25. privateScrollViewsv01,sv02;
  26. privateLinearLayoutllTimeWheel;
  27. privateDateDialogListenerlistener;
  28. privateintlastY;
  29. privateintflag;//标记时分
  30. privateintitemHeight;//每一行的高度
  31. privateintpHour,pMinute;//初始化时显示的时分时间
  32. privateintsetHour,setMinute;
  33. publicCustomerDateDialog(Contextcontext,inthour,intminute){
  34. super(context,R.style.CustomerDateDialog);
  35. customView=LayoutInflater.from(context).inflate(R.layout.time_wheel,
  36. null);
  37. init(context,hour,minute);
  38. }
  39. @Override
  40. protectedvoidonCreate(BundlesavedInstanceState){
  41. super.onCreate(savedInstanceState);
  42. this.setContentView(customView);
  43. }
  44. privatevoidinit(Contextcontext,finalinthour,finalintminute){
  45. tv01=(TextView)customView.findViewById(R.id.tv01);
  46. tv02=(TextView)customView.findViewById(R.id.tv02);
  47. sv01=(ScrollView)customView.findViewById(R.id.sv01);
  48. sv02=(ScrollView)customView.findViewById(R.id.sv02);
  49. setBtn=(Button)customView.findViewById(R.id.setBtn);
  50. cancleBtn=(Button)customView.findViewById(R.id.cancleBtn);
  51. arrow_up=(TextView)customView.findViewById(R.id.arrow_up);
  52. this.pHour=hour;
  53. this.pMinute=minute;
  54. setHour=pHour;
  55. setMinute=pMinute;
  56. llTimeWheel=(LinearLayout)customView
  57. .findViewById(R.id.ll_time_wheel);
  58. setHourDial(tv01);
  59. setMinuteDial(tv02);
  60. sv01.setOnTouchListener(tListener);
  61. sv02.setOnTouchListener(tListener);
  62. finalViewTreeObserverobserver=sv01.getViewTreeObserver();//observer
  63. //作用当视图完全加载进来的时候再取控件的高度,否则取得值是0
  64. observer.addOnGlobalLayoutListener(newOnGlobalLayoutListener(){
  65. @SuppressWarnings("deprecation")
  66. publicvoidonGlobalLayout(){
  67. inttvHeight=tv02.getHeight();
  68. itemHeight=tvHeight/180;
  69. if(sv01.getViewTreeObserver().isAlive()){
  70. sv01.getViewTreeObserver().removeGlobalOnLayoutListener(
  71. this);
  72. }
  73. LinearLayout.LayoutParamsparams=newLinearLayout.LayoutParams(
  74. LinearLayout.LayoutParams.FILL_PARENT,(itemHeight*3)
  75. +arrow_up.getHeight()*2);
  76. llTimeWheel.setLayoutParams(params);
  77. sv01.setLayoutParams(newLinearLayout.LayoutParams(tv02
  78. .getWidth(),(itemHeight*3)));
  79. sv02.setLayoutParams(newLinearLayout.LayoutParams(tv02
  80. .getWidth(),(itemHeight*3)));
  81. sv01.scrollTo(0,(pHour+23)*itemHeight);
  82. sv02.scrollTo(0,(pMinute+59)*itemHeight);
  83. }
  84. });
  85. setBtn.setOnClickListener(newView.OnClickListener(){
  86. @Override
  87. publicvoidonClick(Viewv){
  88. getSettingDate();
  89. CustomerDateDialog.this.cancel();
  90. }
  91. });
  92. cancleBtn.setOnClickListener(newView.OnClickListener(){
  93. @Override
  94. publicvoidonClick(Viewv){
  95. CustomerDateDialog.this.cancel();
  96. }
  97. });
  98. }
  99. privateOnTouchListenertListener=newOnTouchListener(){
  100. publicbooleanonTouch(Viewv,MotionEventevent){
  101. if(v==sv01){
  102. flag=1;
  103. }else{
  104. flag=2;
  105. }
  106. if(event.getAction()==MotionEvent.ACTION_UP){
  107. finalScrollViewsv=(ScrollView)v;
  108. lastY=sv.getScrollY();
  109. System.out.println("lastY"+lastY);
  110. handler.sendMessageDelayed(handler.obtainMessage(0,v),50);
  111. }
  112. returnfalse;
  113. }
  114. };
  115. privateHandlerhandler=newHandler(){
  116. @SuppressLint("HandlerLeak")
  117. publicvoidhandleMessage(android.os.Messagemsg){
  118. ScrollViewsv=(ScrollView)msg.obj;
  119. if(msg.what==0){
  120. if(lastY==sv.getScrollY()){
  121. intnum=lastY/itemHeight;
  122. intover=lastY%itemHeight;
  123. if(over>itemHeight/2){//超过一半滚到下一格
  124. locationTo((num+1)*itemHeight,sv,flag);
  125. }else{//不到一半滚回上一格
  126. locationTo(num*itemHeight,sv,flag);
  127. }
  128. }else{
  129. lastY=sv.getScrollY();
  130. handler.sendMessageDelayed(handler.obtainMessage(0,sv),50);//滚动还没停止隔50毫秒再判断
  131. }
  132. }
  133. };
  134. };
  135. privatevoidlocationTo(intposition,ScrollViewscrollview,intflag){
  136. switch(flag){
  137. case1:
  138. intmPosition=0;
  139. if(position<=23*itemHeight){
  140. mPosition=position+24*itemHeight;
  141. scrollview.scrollTo(0,mPosition);
  142. }elseif(position>=48*itemHeight){
  143. mPosition=position-24*itemHeight;
  144. scrollview.scrollTo(0,mPosition);
  145. }else{
  146. mPosition=position;
  147. scrollview.smoothScrollTo(0,position);
  148. }
  149. setHour=(mPosition/itemHeight-23)%24;
  150. break;
  151. case2:
  152. inthPosition=0;
  153. if(position<=57*itemHeight){
  154. hPosition=position+60*itemHeight;
  155. scrollview.scrollTo(0,hPosition);
  156. }elseif(position>=120*itemHeight){
  157. hPosition=position-60*itemHeight;
  158. scrollview.scrollTo(0,hPosition);
  159. }else{
  160. hPosition=position;
  161. scrollview.smoothScrollTo(0,position);
  162. }
  163. setMinute=(hPosition/itemHeight)%60+1;
  164. break;
  165. }
  166. }
  167. /**
  168. *设置分刻度盘
  169. *
  170. *@paramtv
  171. */
  172. privatevoidsetMinuteDial(TextViewtv){
  173. StringBufferbuff=newStringBuffer();
  174. for(inti=0;i<3;i++){
  175. for(intj=0;j<60;j++){
  176. if(j<=9){
  177. buff.append("0"+j);
  178. }else{
  179. buff.append(j+"");
  180. }
  181. }
  182. }
  183. tv.setText(buff);
  184. }
  185. /**
  186. *设置时刻度盘
  187. *
  188. *@paramtv
  189. */
  190. privatevoidsetHourDial(TextViewtv){
  191. StringBufferbuff=newStringBuffer();
  192. for(inti=0;i<3;i++){
  193. for(intj=0;j<24;j++){
  194. if(j<=9){
  195. buff.append("0"+j);
  196. }else{
  197. buff.append(j+"");
  198. }
  199. }
  200. }
  201. tv.setText(buff);
  202. }
  203. publicvoidsetpHour(intpHour){
  204. this.pHour=pHour;
  205. }
  206. publicvoidsetpMinute(intpMinute){
  207. this.pMinute=pMinute;
  208. }
  209. publicvoidsetOnDateDialogListener(DateDialogListenerlistener){
  210. this.listener=listener;
  211. }
  212. publicinterfaceDateDialogListener{
  213. voidgetDate();
  214. }
  215. publicvoidgetSettingDate(){
  216. if(listener!=null){
  217. listener.getDate();
  218. }
  219. }
  220. publicintgetSettingHour(){
  221. returnsetHour;
  222. }
  223. publicintgetSettingMinute(){
  224. returnsetMinute;
  225. }
  226. }

这里光有java代码还不够,还有自定义Dialog的布局文件,time_wheel.xml代码如下:
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:background="#efefef"
  6. android:orientation="vertical">
  7. <TextView
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:background="@color/light_black"
  11. android:paddingLeft="10dp"
  12. android:text="设置时间"
  13. android:textColor="@color/black"
  14. android:textSize="24sp"/>
  15. <!--时间的相关设置-->
  16. <LinearLayout
  17. android:id="@+id/ll_time_wheel"
  18. android:layout_width="fill_parent"
  19. android:layout_height="wrap_content"
  20. android:layout_marginTop="15dp"
  21. android:background="#f0f0f0"
  22. android:gravity="center_horizontal"
  23. android:orientation="horizontal">
  24. <LinearLayout
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:orientation="vertical">
  28. <TextView
  29. android:layout_width="30dp"
  30. android:layout_height="wrap_content"
  31. android:layout_gravity="center_horizontal"
  32. android:background="@drawable/wheel_arrow_up"/>
  33. <ScrollView
  34. android:id="@+id/sv01"
  35. android:layout_width="50dp"
  36. android:layout_height="wrap_content"
  37. android:layout_gravity="center_horizontal"
  38. android:background="@drawable/time_bg"
  39. android:scrollbars="none">
  40. <LinearLayout
  41. android:id="@+id/ll01"
  42. android:layout_width="50dp"
  43. android:layout_height="wrap_content"
  44. android:gravity="center"
  45. android:orientation="horizontal"
  46. android:paddingTop="5dp">
  47. <TextView
  48. android:id="@+id/tv01"
  49. android:layout_width="50dp"
  50. android:layout_height="wrap_content"
  51. android:gravity="center"
  52. android:lineSpacingExtra="20dp"
  53. android:paddingLeft="10dp"
  54. android:paddingRight="10dp"
  55. android:textSize="26sp"/>
  56. </LinearLayout>
  57. </ScrollView>
  58. <TextView
  59. android:layout_width="30dp"
  60. android:layout_height="wrap_content"
  61. android:layout_gravity="center_horizontal"
  62. android:background="@drawable/wheel_arrow_down"/>
  63. </LinearLayout>
  64. <TextView
  65. android:layout_width="wrap_content"
  66. android:layout_height="fill_parent"
  67. android:layout_gravity="center"
  68. android:background="#f0f0f0"
  69. android:gravity="center"
  70. android:text="时"
  71. android:textColor="#000000"
  72. android:textSize="25sp"/>
  73. <LinearLayout
  74. android:layout_width="wrap_content"
  75. android:layout_height="wrap_content"
  76. android:orientation="vertical">
  77. <TextView
  78. android:id="@+id/arrow_up"
  79. android:layout_width="30dp"
  80. android:layout_height="wrap_content"
  81. android:layout_gravity="center_horizontal"
  82. android:background="@drawable/wheel_arrow_up"/>
  83. <ScrollView
  84. android:id="@+id/sv02"
  85. android:layout_width="50dp"
  86. android:layout_height="wrap_content"
  87. android:layout_gravity="center_horizontal"
  88. android:background="@drawable/time_bg"
  89. android:scrollbars="none">
  90. <LinearLayout
  91. android:id="@+id/ll02"
  92. android:layout_width="50dp"
  93. android:layout_height="wrap_content"
  94. android:gravity="center"
  95. android:paddingTop="5dp">
  96. <TextView
  97. android:id="@+id/tv02"
  98. android:layout_width="50dp"
  99. android:layout_height="wrap_content"
  100. android:gravity="center"
  101. android:lineSpacingExtra="20dp"
  102. android:paddingLeft="10dp"
  103. android:paddingRight="10dp"
  104. android:textSize="26sp"/>
  105. </LinearLayout>
  106. </ScrollView>
  107. <TextView
  108. android:id="@+id/arrow_down"
  109. android:layout_width="30dp"
  110. android:layout_height="wrap_content"
  111. android:layout_gravity="center_horizontal"
  112. android:background="@drawable/wheel_arrow_down"/>
  113. </LinearLayout>
  114. <TextView
  115. android:layout_width="wrap_content"
  116. android:layout_height="fill_parent"
  117. android:layout_gravity="center"
  118. android:background="#f0f0f0"
  119. android:gravity="center"
  120. android:text="分"
  121. android:textColor="#000000"
  122. android:textSize="25sp"/>
  123. </LinearLayout>
  124. <!--设置时钟的按钮-->
  125. <RelativeLayout
  126. android:layout_width="fill_parent"
  127. android:layout_height="50dp">
  128. <Button
  129. android:id="@+id/setBtn"
  130. android:layout_width="wrap_content"
  131. android:layout_height="wrap_content"
  132. android:layout_alignParentLeft="true"
  133. android:layout_gravity="center_horizontal"
  134. android:layout_marginLeft="25dp"
  135. android:background="@drawable/btn_clock_normal"
  136. android:gravity="center"
  137. android:paddingLeft="10dp"
  138. android:paddingRight="10dp"
  139. android:text="确定"
  140. android:textColor="#000000"
  141. android:textSize="24sp"/>
  142. <Button
  143. android:id="@+id/cancleBtn"
  144. android:layout_width="wrap_content"
  145. android:layout_height="wrap_content"
  146. android:layout_alignParentRight="true"
  147. android:layout_gravity="center_horizontal"
  148. android:layout_marginRight="25dp"
  149. android:background="@drawable/btn_clock_normal"
  150. android:gravity="center"
  151. android:paddingLeft="10dp"
  152. android:paddingRight="10dp"
  153. android:text="取消"
  154. android:textColor="#000000"
  155. android:textSize="24sp"/>
  156. </RelativeLayout>
  157. </LinearLayout>

为了让自定义的Dialog的样式更好看,这里还需要自定义样式的Style,Style的代码如下;
  1. <stylename="CustomerDateDialog"parent="@android:Theme.Dialog">
  2. <itemname="android:windowFrame">@null</item>
  3. <itemname="android:windowNoTitle">true</item>
  4. <itemname="android:windowBackground">@color/light_grey</item>
  5. <itemname="android:windowIsFloating">true</item>
  6. <itemname="android:windowContentOverlay">@null</item>
  7. </style>

到这里基本上就完了。你看懂了吗?好好研究吧!

免责声明:文章转载自《Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SpringBoot实现文件上传下载团队介绍&amp;amp;学长采访下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[HTML5]WAI-ARIA介绍

认识ARIA 目前互联网应用日益增强,其中大部分是通过混合技术(AJAX、DHTML、JavaScript 和 SVG)创建或自定义一些模拟桌面GUI程序的的 Web widget 小组件来增强 Web 应用程序的交互,但部分类似Dialog 的对话框、弹出层,模拟select 的下拉菜单等小组件并没能提供所需的语义作支持,残障人士有可能无法读懂当前信息。...

css基础-2 div布局

div布局   <html>         <head>                 <title>div布局 </title>                 <meta charset="utf-8">                 <style>       .toubu...

HTML5+CSS3

0、常用技巧  1)使几个盒子在同一行不换行地靠左且上下居中 /* 弹性盒子 */display: flex;justify-content:flex-start;align-items:center;flex-wrap:nowrap; 1、css基本考点问题 1)、什么是样式表,样式表是由一条条规则组成的,而一条规则由选择器+声明块组成,声...

手机QQ后台清理不掉的秘密——anddroid悬浮窗

问题来自于一篇文章:手机QQ后台为何清不掉?MIUIproject师:全靠1像素的页面保命 出于好奇,想知道这一像素究竟是啥东西,用手机安全管家控制QQ的悬浮窗权限: 关闭QQ的悬浮窗权限,通过后台一键清理,又一次打开QQ,发现是从splash開始的; 打开QQ的悬浮窗权限,一键清理后,打开QQ。发现是直接进入主界面的。说明一键清理未清理QQ,或者清理之...

Bootstrap-菜单,导航,按钮

1、下拉菜单(基本用法) 在Bootstrap框架中的下拉菜单组件是一个独立的组件,根据不同的版本,它对应的文件:   ☑  LESS版本:对应的源码文件为 dropdowns.less   ☑  Sass版本:对应的源码文件为 _dropdowns.scss   ☑  编译后的Bootstrap版本:查看bootstrap.css文件第3004行~第31...

CSS3动画特效——transform详解

CSS3动画特效——transform详解  还可以和过渡属性(Transition)连用      transition&transform,CSS中过度和变形的设置 前置属性: transform-origin更改一个元素变形的原点transform-style:设置元素的子元素是位于 3D 空间中还是平面中 flat:平面,如果选择平面即此...