前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果

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

作者头像
非著名程序员
发布2018-02-01 15:06:42
7810
发布2018-02-01 15:06:42
举报
文章被收录于专栏:非著名程序员非著名程序员

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

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

[html] view plaincopy在CODE上查看代码片派生到我的代码片

代码语言:js
复制
<?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的代码,代码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

代码语言:js
复制
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的代码分享一下,代码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片

代码语言:js
复制
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;  
  }  
}  

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2014-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 非著名程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档