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

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns: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. package net.loonggg.test;
  2. import net.loonggg.view.CustomerDateDialog;
  3. import net.loonggg.view.CustomerDateDialog.DateDialogListener;
  4. import android.app.Activity;
  5. import android.os.Bundle;
  6. import android.text.format.DateFormat;
  7. import android.view.View;
  8. import android.view.Window;
  9. import android.widget.Button;
  10. import android.widget.Toast;
  11. public class MainActivity extends Activity {
  12. private int h, m;
  13. private CustomerDateDialog dialog;
  14. private Button btn;
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  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(new View.OnClickListener() {
  22. @Override
  23. public void onClick(View v) {
  24. String datetime = 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 = new CustomerDateDialog(MainActivity.this, h, m);
  30. dialog.show();
  31. dialog.setOnDateDialogListener(new DateDialogListener() {
  32. @Override
  33. public void getDate() {
  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. package net.loonggg.view;
  2. import net.loonggg.test.R;
  3. import android.annotation.SuppressLint;
  4. import android.app.Dialog;
  5. import android.content.Context;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.view.LayoutInflater;
  9. import android.view.MotionEvent;
  10. import android.view.View;
  11. import android.view.View.OnTouchListener;
  12. import android.view.ViewTreeObserver;
  13. import android.view.ViewTreeObserver.OnGlobalLayoutListener;
  14. import android.widget.Button;
  15. import android.widget.LinearLayout;
  16. import android.widget.ScrollView;
  17. import android.widget.TextView;
  18. @SuppressLint("HandlerLeak")
  19. public class CustomerDateDialog extends Dialog {
  20. private View customView;
  21. private Button setBtn;
  22. private Button cancleBtn;
  23. private TextView arrow_up;
  24. private TextView tv01, tv02;
  25. private ScrollView sv01, sv02;
  26. private LinearLayout llTimeWheel;
  27. private DateDialogListener listener;
  28. private int lastY;
  29. private int flag;// 标记时分
  30. private int itemHeight;// 每一行的高度
  31. private int pHour, pMinute;// 初始化时显示的时分时间
  32. private int setHour, setMinute;
  33. public CustomerDateDialog(Context context, int hour, int minute) {
  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. protected void onCreate(Bundle savedInstanceState) {
  41. super.onCreate(savedInstanceState);
  42. this.setContentView(customView);
  43. }
  44. private void init(Context context, final int hour, final int minute) {
  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. final ViewTreeObserver observer = sv01.getViewTreeObserver();// observer
  63. // 作用当视图完全加载进来的时候再取控件的高度,否则取得值是0
  64. observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  65. @SuppressWarnings("deprecation")
  66. public void onGlobalLayout() {
  67. int tvHeight = tv02.getHeight();
  68. itemHeight = tvHeight / 180;
  69. if (sv01.getViewTreeObserver().isAlive()) {
  70. sv01.getViewTreeObserver().removeGlobalOnLayoutListener(
  71. this);
  72. }
  73. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  74. LinearLayout.LayoutParams.FILL_PARENT, (itemHeight * 3)
  75. + arrow_up.getHeight() * 2);
  76. llTimeWheel.setLayoutParams(params);
  77. sv01.setLayoutParams(new LinearLayout.LayoutParams(tv02
  78. .getWidth(), (itemHeight * 3)));
  79. sv02.setLayoutParams(new LinearLayout.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(new View.OnClickListener() {
  86. @Override
  87. public void onClick(View v) {
  88. getSettingDate();
  89. CustomerDateDialog.this.cancel();
  90. }
  91. });
  92. cancleBtn.setOnClickListener(new View.OnClickListener() {
  93. @Override
  94. public void onClick(View v) {
  95. CustomerDateDialog.this.cancel();
  96. }
  97. });
  98. }
  99. private OnTouchListener tListener = new OnTouchListener() {
  100. public boolean onTouch(View v, MotionEvent event) {
  101. if (v == sv01) {
  102. flag = 1;
  103. } else {
  104. flag = 2;
  105. }
  106. if (event.getAction() == MotionEvent.ACTION_UP) {
  107. final ScrollView sv = (ScrollView) v;
  108. lastY = sv.getScrollY();
  109. System.out.println("lastY" + lastY);
  110. handler.sendMessageDelayed(handler.obtainMessage(0, v), 50);
  111. }
  112. return false;
  113. }
  114. };
  115. private Handler handler = new Handler() {
  116. @SuppressLint("HandlerLeak")
  117. public void handleMessage(android.os.Message msg) {
  118. ScrollView sv = (ScrollView) msg.obj;
  119. if (msg.what == 0) {
  120. if (lastY == sv.getScrollY()) {
  121. int num = lastY / itemHeight;
  122. int over = 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. private void locationTo(int position, ScrollView scrollview, int flag) {
  136. switch (flag) {
  137. case 1:
  138. int mPosition = 0;
  139. if (position <= 23 * itemHeight) {
  140. mPosition = position + 24 * itemHeight;
  141. scrollview.scrollTo(0, mPosition);
  142. } else if (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. case 2:
  152. int hPosition = 0;
  153. if (position <= 57 * itemHeight) {
  154. hPosition = position + 60 * itemHeight;
  155. scrollview.scrollTo(0, hPosition);
  156. } else if (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. * @param tv
  171. */
  172. private void setMinuteDial(TextView tv) {
  173. StringBuffer buff = new StringBuffer();
  174. for (int i = 0; i < 3; i++) {
  175. for (int j = 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. * @param tv
  189. */
  190. private void setHourDial(TextView tv) {
  191. StringBuffer buff = new StringBuffer();
  192. for (int i = 0; i < 3; i++) {
  193. for (int j = 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. public void setpHour(int pHour) {
  204. this.pHour = pHour;
  205. }
  206. public void setpMinute(int pMinute) {
  207. this.pMinute = pMinute;
  208. }
  209. public void setOnDateDialogListener(DateDialogListener listener) {
  210. this.listener = listener;
  211. }
  212. public interface DateDialogListener {
  213. void getDate();
  214. }
  215. public void getSettingDate() {
  216. if (listener != null) {
  217. listener.getDate();
  218. }
  219. }
  220. public int getSettingHour() {
  221. return setHour;
  222. }
  223. public int getSettingMinute() {
  224. return setMinute;
  225. }
  226. }

这里光有java代码还不够,还有自定义Dialog的布局文件,time_wheel.xml代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns: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. <style name="CustomerDateDialog" parent="@android:Theme.Dialog">
  2. <item name="android:windowFrame">@null</item>
  3. <item name="android:windowNoTitle">true</item>
  4. <item name="android:windowBackground">@color/light_grey</item>
  5. <item name="android:windowIsFloating">true</item>
  6. <item name="android:windowContentOverlay">@null</item>
  7. </style>

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

Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果的更多相关文章

  1. Android 学习笔记之Volley(七)实现Json数据加载和解析...

    学习内容: 1.使用Volley实现异步加载Json数据...   Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...

  2. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  3. android学习笔记36——使用原始XML文件

    XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...

  4. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  5. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  6. Android学习笔记36:使用SQLite方式存储数据

    在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...

  7. Android学习笔记之Activity详解

    1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...

  8. Pro Android学习笔记 ActionBar(1):Home图标区

     Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...

  9. 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...

随机推荐

  1. azkaban调度

    azkaban调度 1.概述 azkaban是一套调度系统,常用大数据作业调度.azkaban包括web和executor两套程序,web主要完成展示和交互,executor上完成调度和作业提交执行. ...

  2. 概念:静态static相关知识

    在面向对象中,有‘静态’概念,通过关键字static进行说明, 例如: 静态属性:public static $name = '小仓鼠' 静态方法:public static function Nam ...

  3. String Painter, Chengdu 2008, LA4394

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. Selenium入门13 cookie的增删改查

    cookie的增删改查: 查询:get_cookies()查询所有cookie,get_cookie(cookie的name)获取单个cookie 删除:delete_cookie(cookie的na ...

  5. 雷达覆盖,贪心,类似活动安排(POJ1328)

    题目链接:http://poj.org/problem?id=1328 解题报告: 1.按照头结点排序. #include <cstdio> #include <cmath> ...

  6. 找父节点和子节点个数(Poj1634)

    题目链接:http://poj.org/problem?id=1634 思路:按照工资从小到大排好,找到最近的那个身高较高的人. 有一点要注意的是,这里有个根节点,大boss,他的id是0,因此,我这 ...

  7. HTTP的三次握手

    在讲三次握手之前,希望大家理解一个概念,什么概念呢? 就是在我们的客户端和我们的服务器之间进行http请求,发送和返回的过程当中,我们是需要去创建一个tcp connection的东西,因为http是 ...

  8. Angular2入门--架构概览

    Angular 介绍 Angular 是一款来自谷歌的开源的web前端框架,诞生于2009年,是一款优秀的前端JS框架,已经被用于谷歌的多款产品. Angular 基于Typescript开发 ,更适 ...

  9. 继续折腾LNK 2005错误

    这次是因为要把一个很久的老项目改成使用Unicode字符集,又一次遇到了LNK 2005错误 先说说怎么把老项目改成Unicode字符集吧,首先要有足够的信心能把项目改好,比如我这次改的项目,也不算很 ...

  10. Java 执行系统命令工具类(commons-exec)

    依赖jar <!-- 可以在JVM中可靠地执行外部进程的库. --> <dependency> <groupId>org.apache.commons</gr ...