• 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>

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

    求源码,请关注微信订阅号:smart_android,微信名:非著名程序员,关注成功后,给微信号发送您的邮箱,源码就会发到您的邮箱里。发送格式:发送内容+您的邮箱(内容即为你要的源码内容)

    非著名程序员可能是东半球最好的技术分享公众号。每天,每周定时推送一些有关移动开发的原创文章和教程,微信号:smart_android。
  • 相关阅读:
    [Oracle] CPU/PSU补丁安装详细教程
    weblogic 升级bsu_Weblogic补丁升级之坑坑洼洼
    weblogic补丁下载与安装补丁的方法
    weblogic补丁安装失败
    【项目】项目56
    【项目】项目55
    【项目】项目54
    【项目】项目53
    【项目】项目52
    【项目】项目51
  • 原文地址:https://www.cnblogs.com/loonggg/p/4981840.html
Copyright © 2020-2023  润新知