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

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

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

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

<?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上查看代码片派生到我的代码片

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上查看代码片派生到我的代码片

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;  
  }  
}  

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

原文发布于微信公众号 - 非著名程序员(non-famous-coder)

原文发表时间:2014-11-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区

领取腾讯云代金券