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手机闹钟服务AlarmManagerk开发案例
  • 简单实现Android闹钟程序 附源码
  • Android闹钟设置的解决方案
  • Android编程闹钟设置方法详解
  • Android自定义View 实现闹钟唤起播放闹钟铃声功能
  • 简单实现Android闹钟功能
  • Android闹钟机制实现定时任务功能
  • Android如何在App中启动系统闹钟
  • Android使用CountDownTimer类实现倒计时闹钟
  • android用闹钟定时做http请求推送的解决方案
(0)

相关推荐

  • Android自定义View 实现闹钟唤起播放闹钟铃声功能

    先上图看一下闹钟唤期页面的效果 实现的功能: 1:转动的图片根据天气情况更换 2:转动时间可以设置,转动结束,闹铃声音就结束 3:光圈颜色渐变效果 直接上代码啦: package com.yuekong.sirius.extension.customview; import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import andro

  • Android闹钟机制实现定时任务功能

    Android的闹钟实现机制, 需要调用AlarmManager.set()将闹铃时间记录到系统中,当闹铃时间到后,系统会给应用程序发送广播,我们只需要去注册广播接收器就可以了. 本文分三部分讲解如何实现闹钟: 目录: 1. 设置闹铃时间; 2. 接收闹铃事件广播; 3. 重开机后重新计算并设置闹铃时间; 1. 设置闹铃时间(毫秒) private void setAlarmTime(Context context, long triggerAtMillis) { AlarmManager am

  • Android手机闹钟服务AlarmManagerk开发案例

    AlarmManager通常用来开发手机闹钟,并且它是一个全局定时器,可在指定时间或指定周期启动其他组件(包括Activity,Service,BroadcastReceiver) 获取AlarmManager对象: getSystemService(Service.ALARM_SERVICE) 调用其中的方式设置定时器启动指定组件: set(int type,long triggerAtTime,PendingIntent operation)设置在TriggerAtTime时间启动由oper

  • 简单实现Android闹钟程序 附源码

    这个应用实现了简单的闹钟功能,关闭程序的状态中也可以进行闹钟的提醒. 这里遗留了一个问题: 如果我通过应用本身关闭程序,是可以实现我上述所说的功能,但是如果我在手机进程管理中实现应用程序的关闭操作,这个提醒就不起作用了,我很疑惑的是,我通过应用程序本身关闭了后,在进程中也是查看不到这个应用了的.所以哪位知道的帮留个言指点下,谢谢. ClockDemo.java package com.example.clock; import java.util.Calendar; import android

  • 简单实现Android闹钟功能

    闹钟的简单实现,只有显示时间和设置闹钟. AlarmView package com.example.lenovo.clock2; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.TimePickerDialog; import android.content.Context; import android.content.DialogInterface; import a

  • android用闹钟定时做http请求推送的解决方案

    设计思路 如果在开发当中需要做push接入,而产品又要求不允许用第三方sdk(百度push,友盟push),而且又没有网络编程的经验,这个时候怎么办?这里就给大家分享下用http请求解决这个问题. 大体的设计思路是,写一个service(为了保证长时间运行不被kill,就将其定义到另外的进程当中去),在这个service里面启动闹钟,每隔一段时间(这个时间可以自己定义)去请求服务器,如果有新的push消息,就通知给用户. 具体实现 貌似很简单定义一个闹钟不断轮循请求服务器一句话,却在实际开发中要

  • Android如何在App中启动系统闹钟

    由于不同Android手机厂商提供的系统闹钟包名都不一致,所以只能通过过滤当前手机所有的应用,以确定闹钟应用的包名,进而启动它. 这里采用的过滤规则是:系统应用 && 应用的PackageName包含"widget" 和 "clock" 1.布局文件  activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&

  • Android闹钟设置的解决方案

    Android设置闹钟并不像IOS那样这么简单,做过Android设置闹钟的开发者都知道里面的坑有多深.下面记录一下,我解决Android闹钟设置的解决方案. 主要问题 1.API19开始AlarmManager的机制修改. 2.应用程序被Kill掉后,设置的闹钟不响. 3.6.0以上进入Doze模式会使JobScheduler停止工作. 4.手机设置重启后,闹钟失效问题. API19以上AlarmManager机制的修改 API19之前AlarmManager提供了三个设置闹钟的方法,由于业务

  • Android使用CountDownTimer类实现倒计时闹钟

    下面使用CountDownTimer类实现倒计时小闹钟,CountDownTimer类其实很简单,一般只需重写其onFinish和onTick方法就可以实现倒计时小闹钟,代码如下: MainActivity: package com.home.brewclock; import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.os.CountDownT

  • Android编程闹钟设置方法详解

    本文实例讲述了Android编程闹钟设置方法.分享给大家供大家参考,具体如下: 闹钟在生活中最常见了,在Android中可以通过AlarmManager来实现闹钟,AlarmManager类专门用来设置在某个指定的时间去完成指定的时间.AlarmManager就会通过onReceive()方法去执行这些事件,就算系统处于待机状态,同样不会影响运行.可以通过Context.getSystemService方法来获得该服务.AlarmManager中的方法不少,如下: 方法 说明 Cancel 取消

随机推荐