Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果
看到正点闹钟上的设置时间的滑动效果非常好看,自己就想做一个那样的,在网上就开始搜资料了,看到网上有的齿轮效果的代码非常多,也非常难懂,我就决定自己研究一下,现在我就把我的研究成果分享给大家。我研究的这个效果出来了,而且代码也非常简单,通俗易懂。效果图如下:
首先是MainActivity的布局文件,这个布局文件非常简单,就是一个Button:activity_main.xml文件,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/ll_timeset"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#ffffff"
- android:orientation="vertical" >
- <Button
- android:id="@+id/btn"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="时间设置"
- android:textSize="24sp" />
- </LinearLayout>
紧接着就是MainActivity的代码,代码如下:
- package net.loonggg.test;
- import net.loonggg.view.CustomerDateDialog;
- import net.loonggg.view.CustomerDateDialog.DateDialogListener;
- import android.app.Activity;
- import android.os.Bundle;
- import android.text.format.DateFormat;
- import android.view.View;
- import android.view.Window;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private int h, m;
- private CustomerDateDialog dialog;
- private Button btn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- btn = (Button) findViewById(R.id.btn);
- btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String datetime = DateFormat.format("kk:mm",
- System.currentTimeMillis()).toString();
- String[] strs = datetime.split(":");
- h = Integer.parseInt(strs[0]);
- m = Integer.parseInt(strs[1]);
- dialog = new CustomerDateDialog(MainActivity.this, h, m);
- dialog.show();
- dialog.setOnDateDialogListener(new DateDialogListener() {
- @Override
- public void getDate() {
- Toast.makeText(
- MainActivity.this,
- "时间是:" + dialog.getSettingHour() + "点"
- + dialog.getSettingMinute() + "分",
- Toast.LENGTH_LONG).show();
- }
- });
- }
- });
- }
- }
再就是我自定义了一个时钟的Dialog,自定义Dialog也非常简单,自己可以学一下,这方面网上的资料非常多。现在我把我自定义时钟的Dialog的代码分享一下,代码如下:
- package net.loonggg.view;
- import net.loonggg.test.R;
- import android.annotation.SuppressLint;
- import android.app.Dialog;
- import android.content.Context;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnTouchListener;
- import android.view.ViewTreeObserver;
- import android.view.ViewTreeObserver.OnGlobalLayoutListener;
- import android.widget.Button;
- import android.widget.LinearLayout;
- import android.widget.ScrollView;
- import android.widget.TextView;
- @SuppressLint("HandlerLeak")
- public class CustomerDateDialog extends Dialog {
- private View customView;
- private Button setBtn;
- private Button cancleBtn;
- private TextView arrow_up;
- private TextView tv01, tv02;
- private ScrollView sv01, sv02;
- private LinearLayout llTimeWheel;
- private DateDialogListener listener;
- private int lastY;
- private int flag;// 标记时分
- private int itemHeight;// 每一行的高度
- private int pHour, pMinute;// 初始化时显示的时分时间
- private int setHour, setMinute;
- public CustomerDateDialog(Context context, int hour, int minute) {
- super(context, R.style.CustomerDateDialog);
- customView = LayoutInflater.from(context).inflate(R.layout.time_wheel,
- null);
- init(context, hour, minute);
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- this.setContentView(customView);
- }
- private void init(Context context, final int hour, final int minute) {
- tv01 = (TextView) customView.findViewById(R.id.tv01);
- tv02 = (TextView) customView.findViewById(R.id.tv02);
- sv01 = (ScrollView) customView.findViewById(R.id.sv01);
- sv02 = (ScrollView) customView.findViewById(R.id.sv02);
- setBtn = (Button) customView.findViewById(R.id.setBtn);
- cancleBtn = (Button) customView.findViewById(R.id.cancleBtn);
- arrow_up = (TextView) customView.findViewById(R.id.arrow_up);
- this.pHour = hour;
- this.pMinute = minute;
- setHour = pHour;
- setMinute = pMinute;
- llTimeWheel = (LinearLayout) customView
- .findViewById(R.id.ll_time_wheel);
- setHourDial(tv01);
- setMinuteDial(tv02);
- sv01.setOnTouchListener(tListener);
- sv02.setOnTouchListener(tListener);
- final ViewTreeObserver observer = sv01.getViewTreeObserver();// observer
- // 作用当视图完全加载进来的时候再取控件的高度,否则取得值是0
- observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
- @SuppressWarnings("deprecation")
- public void onGlobalLayout() {
- int tvHeight = tv02.getHeight();
- itemHeight = tvHeight / 180;
- if (sv01.getViewTreeObserver().isAlive()) {
- sv01.getViewTreeObserver().removeGlobalOnLayoutListener(
- this);
- }
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.FILL_PARENT, (itemHeight * 3)
- + arrow_up.getHeight() * 2);
- llTimeWheel.setLayoutParams(params);
- sv01.setLayoutParams(new LinearLayout.LayoutParams(tv02
- .getWidth(), (itemHeight * 3)));
- sv02.setLayoutParams(new LinearLayout.LayoutParams(tv02
- .getWidth(), (itemHeight * 3)));
- sv01.scrollTo(0, (pHour + 23) * itemHeight);
- sv02.scrollTo(0, (pMinute + 59) * itemHeight);
- }
- });
- setBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getSettingDate();
- CustomerDateDialog.this.cancel();
- }
- });
- cancleBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- CustomerDateDialog.this.cancel();
- }
- });
- }
- private OnTouchListener tListener = new OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- if (v == sv01) {
- flag = 1;
- } else {
- flag = 2;
- }
- if (event.getAction() == MotionEvent.ACTION_UP) {
- final ScrollView sv = (ScrollView) v;
- lastY = sv.getScrollY();
- System.out.println("lastY" + lastY);
- handler.sendMessageDelayed(handler.obtainMessage(0, v), 50);
- }
- return false;
- }
- };
- private Handler handler = new Handler() {
- @SuppressLint("HandlerLeak")
- public void handleMessage(android.os.Message msg) {
- ScrollView sv = (ScrollView) msg.obj;
- if (msg.what == 0) {
- if (lastY == sv.getScrollY()) {
- int num = lastY / itemHeight;
- int over = lastY % itemHeight;
- if (over > itemHeight / 2) {// 超过一半滚到下一格
- locationTo((num + 1) * itemHeight, sv, flag);
- } else {// 不到一半滚回上一格
- locationTo(num * itemHeight, sv, flag);
- }
- } else {
- lastY = sv.getScrollY();
- handler.sendMessageDelayed(handler.obtainMessage(0, sv), 50);// 滚动还没停止隔50毫秒再判断
- }
- }
- };
- };
- private void locationTo(int position, ScrollView scrollview, int flag) {
- switch (flag) {
- case 1:
- int mPosition = 0;
- if (position <= 23 * itemHeight) {
- mPosition = position + 24 * itemHeight;
- scrollview.scrollTo(0, mPosition);
- } else if (position >= 48 * itemHeight) {
- mPosition = position - 24 * itemHeight;
- scrollview.scrollTo(0, mPosition);
- } else {
- mPosition = position;
- scrollview.smoothScrollTo(0, position);
- }
- setHour = (mPosition / itemHeight - 23) % 24;
- break;
- case 2:
- int hPosition = 0;
- if (position <= 57 * itemHeight) {
- hPosition = position + 60 * itemHeight;
- scrollview.scrollTo(0, hPosition);
- } else if (position >= 120 * itemHeight) {
- hPosition = position - 60 * itemHeight;
- scrollview.scrollTo(0, hPosition);
- } else {
- hPosition = position;
- scrollview.smoothScrollTo(0, position);
- }
- setMinute = (hPosition / itemHeight) % 60 + 1;
- break;
- }
- }
- /**
- * 设置分刻度盘
- *
- * @param tv
- */
- private void setMinuteDial(TextView tv) {
- StringBuffer buff = new StringBuffer();
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 60; j++) {
- if (j <= 9) {
- buff.append("0" + j);
- } else {
- buff.append(j + "");
- }
- }
- }
- tv.setText(buff);
- }
- /**
- * 设置时刻度盘
- *
- * @param tv
- */
- private void setHourDial(TextView tv) {
- StringBuffer buff = new StringBuffer();
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 24; j++) {
- if (j <= 9) {
- buff.append("0" + j);
- } else {
- buff.append(j + "");
- }
- }
- }
- tv.setText(buff);
- }
- public void setpHour(int pHour) {
- this.pHour = pHour;
- }
- public void setpMinute(int pMinute) {
- this.pMinute = pMinute;
- }
- public void setOnDateDialogListener(DateDialogListener listener) {
- this.listener = listener;
- }
- public interface DateDialogListener {
- void getDate();
- }
- public void getSettingDate() {
- if (listener != null) {
- listener.getDate();
- }
- }
- public int getSettingHour() {
- return setHour;
- }
- public int getSettingMinute() {
- return setMinute;
- }
- }
这里光有java代码还不够,还有自定义Dialog的布局文件,time_wheel.xml代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="#efefef"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@color/light_black"
- android:paddingLeft="10dp"
- android:text="设置时间"
- android:textColor="@color/black"
- android:textSize="24sp" />
- <!-- 时间的相关设置 -->
- <LinearLayout
- android:id="@+id/ll_time_wheel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="15dp"
- android:background="#f0f0f0"
- android:gravity="center_horizontal"
- android:orientation="horizontal" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <TextView
- android:layout_width="30dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/wheel_arrow_up" />
- <ScrollView
- android:id="@+id/sv01"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/time_bg"
- android:scrollbars="none" >
- <LinearLayout
- android:id="@+id/ll01"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal"
- android:paddingTop="5dp" >
- <TextView
- android:id="@+id/tv01"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:lineSpacingExtra="20dp"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:textSize="26sp" />
- </LinearLayout>
- </ScrollView>
- <TextView
- android:layout_width="30dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/wheel_arrow_down" />
- </LinearLayout>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_gravity="center"
- android:background="#f0f0f0"
- android:gravity="center"
- android:text="时"
- android:textColor="#000000"
- android:textSize="25sp" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/arrow_up"
- android:layout_width="30dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/wheel_arrow_up" />
- <ScrollView
- android:id="@+id/sv02"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/time_bg"
- android:scrollbars="none" >
- <LinearLayout
- android:id="@+id/ll02"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:paddingTop="5dp" >
- <TextView
- android:id="@+id/tv02"
- android:layout_width="50dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:lineSpacingExtra="20dp"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:textSize="26sp" />
- </LinearLayout>
- </ScrollView>
- <TextView
- android:id="@+id/arrow_down"
- android:layout_width="30dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/wheel_arrow_down" />
- </LinearLayout>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_gravity="center"
- android:background="#f0f0f0"
- android:gravity="center"
- android:text="分"
- android:textColor="#000000"
- android:textSize="25sp" />
- </LinearLayout>
- <!-- 设置时钟的按钮 -->
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="50dp" >
- <Button
- android:id="@+id/setBtn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_gravity="center_horizontal"
- android:layout_marginLeft="25dp"
- android:background="@drawable/btn_clock_normal"
- android:gravity="center"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:text="确定"
- android:textColor="#000000"
- android:textSize="24sp" />
- <Button
- android:id="@+id/cancleBtn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_gravity="center_horizontal"
- android:layout_marginRight="25dp"
- android:background="@drawable/btn_clock_normal"
- android:gravity="center"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:text="取消"
- android:textColor="#000000"
- android:textSize="24sp" />
- </RelativeLayout>
- </LinearLayout>
为了让自定义的Dialog的样式更好看,这里还需要自定义样式的Style,Style的代码如下;
- <style name="CustomerDateDialog" parent="@android:Theme.Dialog">
- <item name="android:windowFrame">@null</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowBackground">@color/light_grey</item>
- <item name="android:windowIsFloating">true</item>
- <item name="android:windowContentOverlay">@null</item>
- </style>
到这里基本上就完了。你看懂了吗?好好研究吧!
Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果的更多相关文章
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- Pro Android学习笔记 ActionBar(1):Home图标区
Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
随机推荐
- So you want to write a desktop app in Python
So you want to write a desktop app in Python Thomas Kluyver 2014-06-16 23:55 51 Comments Source This ...
- 笨办法学Python(三十一)
习题 31: 作出决定 这本书的上半部分你打印了一些东西,而且调用了函数,不过一切都是直线式进行的.你的脚本从最上面一行开始,一路运行到结束,但其中并没有决定程序流向的分支点.现在你已经学了 if, ...
- Jmeter入门8 连接microsoft sql server数据库取数据
本文以Jmeter 连接microsoft sql server为例. 1 从微软官网下载Microsoft SQL Server JDBC Driver 地址:http://www.microsof ...
- 2018.9.3 CEP课程总结
什么是CEP课程? 职业生涯规划课程 蓝桥介绍 立人达人 全人教育 人文 重视人 尊重人 关心人 爱护人 人才 人格 简历的制作 找工作的流程? 1.简历的准备------>投发简历(自己投.老 ...
- 2017.11.6 JavaWeb-----第七章 JavaWeb常用开发模式与案例
JavaWeb-----第七章 JavaWeb常用开发模式与案例 (1)单纯的JSP页面开发模式 通过在JSP中的脚本标记,直接在JSP页面中实现各种功能.称为"单纯的JSP页面编程模式&q ...
- 2017.9.24 JSP动态页面
1.1 JSP(Java Server Page)是一种运行在服务器端的脚本语言,用来开发动态网页的开发技术. 1.2 JSP页面的结构 JSP页面主要由HTML和JSP代码构成,JSP代码是通过&q ...
- python打印对象所有属性
print dict(对象名)
- Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points
Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple ...
- 旧文备份:rtlinux安装手册
前段时间接触了几天RTLinux,折腾了好几天才总算把它安装上,得益于Prof. Chang-Gun Lee的安装建议,觉得该文档可能会对准备尝试安装RTLinux的朋友们有帮助,本人英语很烂,也比较 ...
- 【Java】Maven安装、Eclipse配置以及相关错误解决集合
作者呕血总结,下面写的每一个错误我都遇过 · Maven安装 · Eclipse配置 · Maven安装 安装前请确保已经装有JDK. 一. 准备Maven程序包 到官网https://maven.a ...