Android仿正点闹钟时间齿轮滑动效果

作者:非著名程序员 时间:2022-09-06 09:27:46 

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

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>

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

来源:http://blog.csdn.net/loongggdroid/article/details/9564637

标签:Android,闹钟,齿轮滑动
0
投稿

猜你喜欢

  • C# winform点击生成二维码实例代码

    2023-12-10 08:17:20
  • java代理 jdk动态代理应用案列

    2023-02-17 10:08:55
  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    2022-01-17 12:21:18
  • C#中在WebClient中使用post发送数据实现方法

    2023-05-01 00:03:54
  • Android实现抽奖转盘实例代码

    2021-08-22 20:03:35
  • Android 消息队列模型详解及实例

    2023-04-06 10:49:43
  • Springboot2以代码的方式统一配置Jackson教程

    2021-08-30 16:47:33
  • Object类toString()和equals()方法使用解析

    2022-10-28 08:48:43
  • Java Hibernate对象(瞬时态,持久态,脱管态)详解

    2022-05-22 20:07:32
  • 简单的观察者模式示例分享

    2023-02-11 12:52:12
  • 用C#将图片保存至Oracle BLOB字段中的方法

    2023-06-12 01:29:16
  • C#多线程系列之线程完成数

    2021-12-24 03:07:47
  • Java读取并下载网络文件的方法

    2023-03-18 11:47:05
  • SpringBoot项目修改访问端口和访问路径的方法

    2023-07-13 11:23:35
  • Android中3种全屏方法及3种去掉标题栏的方法

    2023-11-07 18:45:51
  • Spring Security使用中Preflight请求和跨域问题详解

    2021-06-12 11:04:15
  • 三分钟快速掌握Java中枚举(enum)

    2023-11-27 09:46:30
  • C#实现简易计算器功能(附源码)

    2021-07-18 00:16:00
  • Android 使用 okhttp3和retrofit2 进行单文件和多文件上传

    2023-04-29 07:33:22
  • java8新特性 stream流的方式遍历集合和数组操作

    2023-03-29 10:49:25
  • asp之家 软件编程 m.aspxhome.com