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


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

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

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:id="@+id/ll_timeset"  
    4.     android:layout_width="fill_parent"  
    5.     android:layout_height="fill_parent"  
    6.     android:background="#ffffff"  
    7.     android:orientation="vertical" >  
    8.   
    9.     <Button  
    10.         android:id="@+id/btn"  
    11.         android:layout_width="fill_parent"  
    12.         android:layout_height="wrap_content"  
    13.         android:gravity="center"  
    14.         android:text="时间设置"  
    15.         android:textSize="24sp" />  
    16.   
    17. </LinearLayout>  

    紧接着就是MainActivity的代码,代码如下:
    1. package net.loonggg.test;  
    2.   
    3. import net.loonggg.view.CustomerDateDialog;  
    4. import net.loonggg.view.CustomerDateDialog.DateDialogListener;  
    5. import android.app.Activity;  
    6. import android.os.Bundle;  
    7. import android.text.format.DateFormat;  
    8. import android.view.View;  
    9. import android.view.Window;  
    10. import android.widget.Button;  
    11. import android.widget.Toast;  
    12.   
    13. public class MainActivity extends Activity {  
    14.     private int h, m;  
    15.     private CustomerDateDialog dialog;  
    16.     private Button btn;  
    17.   
    18.     @Override  
    19.     protected void onCreate(Bundle savedInstanceState) {  
    20.         super.onCreate(savedInstanceState);  
    21.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
    22.         setContentView(R.layout.activity_main);  
    23.         btn = (Button) findViewById(R.id.btn);  
    24.         btn.setOnClickListener(new View.OnClickListener() {  
    25.   
    26.             @Override  
    27.             public void onClick(View v) {  
    28.                 String datetime = DateFormat.format("kk:mm",  
    29.                         System.currentTimeMillis()).toString();  
    30.                 String[] strs = datetime.split(":");  
    31.                 h = Integer.parseInt(strs[0]);  
    32.                 m = Integer.parseInt(strs[1]);  
    33.                 dialog = new CustomerDateDialog(MainActivity.this, h, m);  
    34.                 dialog.show();  
    35.                 dialog.setOnDateDialogListener(new DateDialogListener() {  
    36.                     @Override  
    37.                     public void getDate() {  
    38.                         Toast.makeText(  
    39.                                 MainActivity.this,  
    40.                                 "时间是:" + dialog.getSettingHour() + "点"  
    41.                                         + dialog.getSettingMinute() + "分",  
    42.                                 Toast.LENGTH_LONG).show();  
    43.                     }  
    44.                 });  
    45.   
    46.             }  
    47.         });  
    48.   
    49.     }  
    50.   
    51. }  

    再就是我自定义了一个时钟的Dialog,自定义Dialog也非常简单,自己可以学一下,这方面网上的资料非常多。现在我把我自定义时钟的Dialog的代码分享一下,代码如下:
    1. package net.loonggg.view;  
    2.   
    3. import net.loonggg.test.R;  
    4. import android.annotation.SuppressLint;  
    5. import android.app.Dialog;  
    6. import android.content.Context;  
    7. import android.os.Bundle;  
    8. import android.os.Handler;  
    9. import android.view.LayoutInflater;  
    10. import android.view.MotionEvent;  
    11. import android.view.View;  
    12. import android.view.View.OnTouchListener;  
    13. import android.view.ViewTreeObserver;  
    14. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
    15. import android.widget.Button;  
    16. import android.widget.LinearLayout;  
    17. import android.widget.ScrollView;  
    18. import android.widget.TextView;  
    19.   
    20. @SuppressLint("HandlerLeak")  
    21. public class CustomerDateDialog extends Dialog {  
    22.     private View customView;  
    23.     private Button setBtn;  
    24.     private Button cancleBtn;  
    25.     private TextView arrow_up;  
    26.     private TextView tv01, tv02;  
    27.     private ScrollView sv01, sv02;  
    28.     private LinearLayout llTimeWheel;  
    29.     private DateDialogListener listener;  
    30.     private int lastY;  
    31.     private int flag;// 标记时分  
    32.     private int itemHeight;// 每一行的高度  
    33.     private int pHour, pMinute;// 初始化时显示的时分时间  
    34.     private int setHour, setMinute;  
    35.   
    36.     public CustomerDateDialog(Context context, int hour, int minute) {  
    37.         super(context, R.style.CustomerDateDialog);  
    38.         customView = LayoutInflater.from(context).inflate(R.layout.time_wheel,  
    39.                 null);  
    40.         init(context, hour, minute);  
    41.     }  
    42.   
    43.     @Override  
    44.     protected void onCreate(Bundle savedInstanceState) {  
    45.         super.onCreate(savedInstanceState);  
    46.         this.setContentView(customView);  
    47.     }  
    48.   
    49.     private void init(Context context, final int hour, final int minute) {  
    50.         tv01 = (TextView) customView.findViewById(R.id.tv01);  
    51.         tv02 = (TextView) customView.findViewById(R.id.tv02);  
    52.         sv01 = (ScrollView) customView.findViewById(R.id.sv01);  
    53.         sv02 = (ScrollView) customView.findViewById(R.id.sv02);  
    54.         setBtn = (Button) customView.findViewById(R.id.setBtn);  
    55.         cancleBtn = (Button) customView.findViewById(R.id.cancleBtn);  
    56.         arrow_up = (TextView) customView.findViewById(R.id.arrow_up);  
    57.         this.pHour = hour;  
    58.         this.pMinute = minute;  
    59.         setHour = pHour;  
    60.         setMinute = pMinute;  
    61.   
    62.         llTimeWheel = (LinearLayout) customView  
    63.                 .findViewById(R.id.ll_time_wheel);  
    64.         setHourDial(tv01);  
    65.         setMinuteDial(tv02);  
    66.   
    67.         sv01.setOnTouchListener(tListener);  
    68.         sv02.setOnTouchListener(tListener);  
    69.   
    70.         final ViewTreeObserver observer = sv01.getViewTreeObserver();// observer  
    71.                                                                         // 作用当视图完全加载进来的时候再取控件的高度,否则取得值是0  
    72.         observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
    73.   
    74.             @SuppressWarnings("deprecation")  
    75.             public void onGlobalLayout() {  
    76.                 int tvHeight = tv02.getHeight();  
    77.                 itemHeight = tvHeight / 180;  
    78.                 if (sv01.getViewTreeObserver().isAlive()) {  
    79.                     sv01.getViewTreeObserver().removeGlobalOnLayoutListener(  
    80.                             this);  
    81.                 }  
    82.                 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(  
    83.                         LinearLayout.LayoutParams.FILL_PARENT, (itemHeight * 3)  
    84.                                 + arrow_up.getHeight() * 2);  
    85.                 llTimeWheel.setLayoutParams(params);  
    86.                 sv01.setLayoutParams(new LinearLayout.LayoutParams(tv02  
    87.                         .getWidth(), (itemHeight * 3)));  
    88.                 sv02.setLayoutParams(new LinearLayout.LayoutParams(tv02  
    89.                         .getWidth(), (itemHeight * 3)));  
    90.                 sv01.scrollTo(0, (pHour + 23) * itemHeight);  
    91.                 sv02.scrollTo(0, (pMinute + 59) * itemHeight);  
    92.   
    93.             }  
    94.         });  
    95.   
    96.         setBtn.setOnClickListener(new View.OnClickListener() {  
    97.   
    98.             @Override  
    99.             public void onClick(View v) {  
    100.                 getSettingDate();  
    101.                 CustomerDateDialog.this.cancel();  
    102.             }  
    103.         });  
    104.   
    105.         cancleBtn.setOnClickListener(new View.OnClickListener() {  
    106.   
    107.             @Override  
    108.             public void onClick(View v) {  
    109.                 CustomerDateDialog.this.cancel();  
    110.             }  
    111.         });  
    112.     }  
    113.   
    114.     private OnTouchListener tListener = new OnTouchListener() {  
    115.   
    116.         public boolean onTouch(View v, MotionEvent event) {  
    117.             if (v == sv01) {  
    118.                 flag = 1;  
    119.             } else {  
    120.                 flag = 2;  
    121.             }  
    122.             if (event.getAction() == MotionEvent.ACTION_UP) {  
    123.                 final ScrollView sv = (ScrollView) v;  
    124.                 lastY = sv.getScrollY();  
    125.                 System.out.println("lastY" + lastY);  
    126.                 handler.sendMessageDelayed(handler.obtainMessage(0, v), 50);  
    127.             }  
    128.             return false;  
    129.         }  
    130.     };  
    131.   
    132.     private Handler handler = new Handler() {  
    133.         @SuppressLint("HandlerLeak")  
    134.         public void handleMessage(android.os.Message msg) {  
    135.             ScrollView sv = (ScrollView) msg.obj;  
    136.   
    137.             if (msg.what == 0) {  
    138.                 if (lastY == sv.getScrollY()) {  
    139.   
    140.                     int num = lastY / itemHeight;  
    141.                     int over = lastY % itemHeight;  
    142.                     if (over > itemHeight / 2) {// 超过一半滚到下一格  
    143.                         locationTo((num + 1) * itemHeight, sv, flag);  
    144.                     } else {// 不到一半滚回上一格  
    145.                         locationTo(num * itemHeight, sv, flag);  
    146.                     }  
    147.                 } else {  
    148.                     lastY = sv.getScrollY();  
    149.                     handler.sendMessageDelayed(handler.obtainMessage(0, sv), 50);// 滚动还没停止隔50毫秒再判断  
    150.                 }  
    151.             }  
    152.   
    153.         };  
    154.     };  
    155.   
    156.     private void locationTo(int position, ScrollView scrollview, int flag) {  
    157.         switch (flag) {  
    158.         case 1:  
    159.             int mPosition = 0;  
    160.             if (position <= 23 * itemHeight) {  
    161.                 mPosition = position + 24 * itemHeight;  
    162.                 scrollview.scrollTo(0, mPosition);  
    163.             } else if (position >= 48 * itemHeight) {  
    164.                 mPosition = position - 24 * itemHeight;  
    165.                 scrollview.scrollTo(0, mPosition);  
    166.             } else {  
    167.                 mPosition = position;  
    168.                 scrollview.smoothScrollTo(0, position);  
    169.             }  
    170.             setHour = (mPosition / itemHeight - 23) % 24;  
    171.             break;  
    172.   
    173.         case 2:  
    174.             int hPosition = 0;  
    175.             if (position <= 57 * itemHeight) {  
    176.                 hPosition = position + 60 * itemHeight;  
    177.                 scrollview.scrollTo(0, hPosition);  
    178.             } else if (position >= 120 * itemHeight) {  
    179.                 hPosition = position - 60 * itemHeight;  
    180.                 scrollview.scrollTo(0, hPosition);  
    181.             } else {  
    182.                 hPosition = position;  
    183.                 scrollview.smoothScrollTo(0, position);  
    184.             }  
    185.             setMinute = (hPosition / itemHeight) % 60 + 1;  
    186.             break;  
    187.         }  
    188.   
    189.     }  
    190.   
    191.     /** 
    192.      * 设置分刻度盘 
    193.      *  
    194.      * @param tv 
    195.      */  
    196.   
    197.     private void setMinuteDial(TextView tv) {  
    198.         StringBuffer buff = new StringBuffer();  
    199.         for (int i = 0; i < 3; i++) {  
    200.             for (int j = 0; j < 60; j++) {  
    201.                 if (j <= 9) {  
    202.                     buff.append("0" + j);  
    203.                 } else {  
    204.                     buff.append(j + "");  
    205.                 }  
    206.             }  
    207.         }  
    208.   
    209.         tv.setText(buff);  
    210.     }  
    211.   
    212.     /** 
    213.      * 设置时刻度盘 
    214.      *  
    215.      * @param tv 
    216.      */  
    217.     private void setHourDial(TextView tv) {  
    218.         StringBuffer buff = new StringBuffer();  
    219.         for (int i = 0; i < 3; i++) {  
    220.             for (int j = 0; j < 24; j++) {  
    221.                 if (j <= 9) {  
    222.                     buff.append("0" + j);  
    223.                 } else {  
    224.                     buff.append(j + "");  
    225.                 }  
    226.             }  
    227.   
    228.         }  
    229.   
    230.         tv.setText(buff);  
    231.     }  
    232.   
    233.     public void setpHour(int pHour) {  
    234.         this.pHour = pHour;  
    235.     }  
    236.   
    237.     public void setpMinute(int pMinute) {  
    238.         this.pMinute = pMinute;  
    239.     }  
    240.   
    241.     public void setOnDateDialogListener(DateDialogListener listener) {  
    242.         this.listener = listener;  
    243.     }  
    244.   
    245.     public interface DateDialogListener {  
    246.         void getDate();  
    247.     }  
    248.   
    249.     public void getSettingDate() {  
    250.         if (listener != null) {  
    251.             listener.getDate();  
    252.         }  
    253.     }  
    254.   
    255.     public int getSettingHour() {  
    256.         return setHour;  
    257.     }  
    258.   
    259.     public int getSettingMinute() {  
    260.         return setMinute;  
    261.     }  
    262.   
    263. }  

    这里光有java代码还不够,还有自定义Dialog的布局文件,time_wheel.xml代码如下:
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="wrap_content"  
    5.     android:background="#efefef"  
    6.     android:orientation="vertical" >  
    7.   
    8.     <TextView  
    9.         android:layout_width="fill_parent"  
    10.         android:layout_height="wrap_content"  
    11.         android:background="@color/light_black"  
    12.         android:paddingLeft="10dp"  
    13.         android:text="设置时间"  
    14.         android:textColor="@color/black"  
    15.         android:textSize="24sp" />  
    16.   
    17.     <!-- 时间的相关设置 -->  
    18.   
    19.     <LinearLayout  
    20.         android:id="@+id/ll_time_wheel"  
    21.         android:layout_width="fill_parent"  
    22.         android:layout_height="wrap_content"  
    23.         android:layout_marginTop="15dp"  
    24.         android:background="#f0f0f0"  
    25.         android:gravity="center_horizontal"  
    26.         android:orientation="horizontal" >  
    27.   
    28.         <LinearLayout  
    29.             android:layout_width="wrap_content"  
    30.             android:layout_height="wrap_content"  
    31.             android:orientation="vertical" >  
    32.   
    33.             <TextView  
    34.                 android:layout_width="30dp"  
    35.                 android:layout_height="wrap_content"  
    36.                 android:layout_gravity="center_horizontal"  
    37.                 android:background="@drawable/wheel_arrow_up" />  
    38.   
    39.             <ScrollView  
    40.                 android:id="@+id/sv01"  
    41.                 android:layout_width="50dp"  
    42.                 android:layout_height="wrap_content"  
    43.                 android:layout_gravity="center_horizontal"  
    44.                 android:background="@drawable/time_bg"  
    45.                 android:scrollbars="none" >  
    46.   
    47.                 <LinearLayout  
    48.                     android:id="@+id/ll01"  
    49.                     android:layout_width="50dp"  
    50.                     android:layout_height="wrap_content"  
    51.                     android:gravity="center"  
    52.                     android:orientation="horizontal"  
    53.                     android:paddingTop="5dp" >  
    54.   
    55.                     <TextView  
    56.                         android:id="@+id/tv01"  
    57.                         android:layout_width="50dp"  
    58.                         android:layout_height="wrap_content"  
    59.                         android:gravity="center"  
    60.                         android:lineSpacingExtra="20dp"  
    61.                         android:paddingLeft="10dp"  
    62.                         android:paddingRight="10dp"  
    63.                         android:textSize="26sp" />  
    64.                 </LinearLayout>  
    65.             </ScrollView>  
    66.   
    67.             <TextView  
    68.                 android:layout_width="30dp"  
    69.                 android:layout_height="wrap_content"  
    70.                 android:layout_gravity="center_horizontal"  
    71.                 android:background="@drawable/wheel_arrow_down" />  
    72.         </LinearLayout>  
    73.   
    74.         <TextView  
    75.             android:layout_width="wrap_content"  
    76.             android:layout_height="fill_parent"  
    77.             android:layout_gravity="center"  
    78.             android:background="#f0f0f0"  
    79.             android:gravity="center"  
    80.             android:text="时"  
    81.             android:textColor="#000000"  
    82.             android:textSize="25sp" />  
    83.   
    84.         <LinearLayout  
    85.             android:layout_width="wrap_content"  
    86.             android:layout_height="wrap_content"  
    87.             android:orientation="vertical" >  
    88.   
    89.             <TextView  
    90.                 android:id="@+id/arrow_up"  
    91.                 android:layout_width="30dp"  
    92.                 android:layout_height="wrap_content"  
    93.                 android:layout_gravity="center_horizontal"  
    94.                 android:background="@drawable/wheel_arrow_up" />  
    95.   
    96.             <ScrollView  
    97.                 android:id="@+id/sv02"  
    98.                 android:layout_width="50dp"  
    99.                 android:layout_height="wrap_content"  
    100.                 android:layout_gravity="center_horizontal"  
    101.                 android:background="@drawable/time_bg"  
    102.                 android:scrollbars="none" >  
    103.   
    104.                 <LinearLayout  
    105.                     android:id="@+id/ll02"  
    106.                     android:layout_width="50dp"  
    107.                     android:layout_height="wrap_content"  
    108.                     android:gravity="center"  
    109.                     android:paddingTop="5dp" >  
    110.   
    111.                     <TextView  
    112.                         android:id="@+id/tv02"  
    113.                         android:layout_width="50dp"  
    114.                         android:layout_height="wrap_content"  
    115.                         android:gravity="center"  
    116.                         android:lineSpacingExtra="20dp"  
    117.                         android:paddingLeft="10dp"  
    118.                         android:paddingRight="10dp"  
    119.                         android:textSize="26sp" />  
    120.                 </LinearLayout>  
    121.             </ScrollView>  
    122.   
    123.             <TextView  
    124.                 android:id="@+id/arrow_down"  
    125.                 android:layout_width="30dp"  
    126.                 android:layout_height="wrap_content"  
    127.                 android:layout_gravity="center_horizontal"  
    128.                 android:background="@drawable/wheel_arrow_down" />  
    129.         </LinearLayout>  
    130.   
    131.         <TextView  
    132.             android:layout_width="wrap_content"  
    133.             android:layout_height="fill_parent"  
    134.             android:layout_gravity="center"  
    135.             android:background="#f0f0f0"  
    136.             android:gravity="center"  
    137.             android:text="分"  
    138.             android:textColor="#000000"  
    139.             android:textSize="25sp" />  
    140.     </LinearLayout>  
    141.   
    142.     <!-- 设置时钟的按钮 -->  
    143.   
    144.     <RelativeLayout  
    145.         android:layout_width="fill_parent"  
    146.         android:layout_height="50dp" >  
    147.   
    148.         <Button  
    149.             android:id="@+id/setBtn"  
    150.             android:layout_width="wrap_content"  
    151.             android:layout_height="wrap_content"  
    152.             android:layout_alignParentLeft="true"  
    153.             android:layout_gravity="center_horizontal"  
    154.             android:layout_marginLeft="25dp"  
    155.             android:background="@drawable/btn_clock_normal"  
    156.             android:gravity="center"  
    157.             android:paddingLeft="10dp"  
    158.             android:paddingRight="10dp"  
    159.             android:text="确定"  
    160.             android:textColor="#000000"  
    161.             android:textSize="24sp" />  
    162.   
    163.         <Button  
    164.             android:id="@+id/cancleBtn"  
    165.             android:layout_width="wrap_content"  
    166.             android:layout_height="wrap_content"  
    167.             android:layout_alignParentRight="true"  
    168.             android:layout_gravity="center_horizontal"  
    169.             android:layout_marginRight="25dp"  
    170.             android:background="@drawable/btn_clock_normal"  
    171.             android:gravity="center"  
    172.             android:paddingLeft="10dp"  
    173.             android:paddingRight="10dp"  
    174.             android:text="取消"  
    175.             android:textColor="#000000"  
    176.             android:textSize="24sp" />  
    177.     </RelativeLayout>  
    178.   
    179. </LinearLayout>  

    为了让自定义的Dialog的样式更好看,这里还需要自定义样式的Style,Style的代码如下;
    1. <style name="CustomerDateDialog" parent="@android:Theme.Dialog">  
    2.         <item name="android:windowFrame">@null</item>  
    3.         <item name="android:windowNoTitle">true</item>  
    4.         <item name="android:windowBackground">@color/light_grey</item>  
    5.         <item name="android:windowIsFloating">true</item>  
    6.         <item name="android:windowContentOverlay">@null</item>  
    7.     </style>  

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


    非著名程序员可能是东半球最好的技术分享公众号。每天,每周定时推送一些有关移动开发的原创文章和教程,微信号:smart_android。
  • 相关阅读:
    SVN的学习
    IIS 503 错误
    Windows系统CMD下常用命令
    Linux基础整理
    JavaEESSM框架配置文件
    JavaXML整理
    Java反射、反射练习整理
    Java网络通信协议、UDP、TCP类加载整理
    Java多线程、线程池和线程安全整理
    JavaProperties类、序列化流与反序列化流、打印流、commons-IO整理
  • 原文地址:https://www.cnblogs.com/loonggg/p/3220760.html
Copyright © 2020-2023  润新知