Android仿正點(diǎn)鬧鐘時(shí)間齒輪滑動效果
看到正點(diǎn)鬧鐘上的設(shè)置時(shí)間的滑動效果非常好看,自己就想做一個(gè)那樣的,在網(wǎng)上就開始搜資料了,看到網(wǎng)上有的齒輪效果的代碼非常多,也非常難懂,我就決定自己研究一下,現(xiàn)在我就把我的研究成果分享給大家。我研究的這個(gè)效果出來了,而且代碼也非常簡單,通俗易懂。效果圖如下:

首先是MainActivity的布局文件,這個(gè)布局文件非常簡單,就是一個(gè)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="時(shí)間設(shè)置"
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,
"時(shí)間是:" + dialog.getSettingHour() + "點(diǎn)"
+ dialog.getSettingMinute() + "分",
Toast.LENGTH_LONG).show();
}
});
}
});
}
}
再就是我自定義了一個(gè)時(shí)鐘的Dialog,自定義Dialog也非常簡單,自己可以學(xué)一下,這方面網(wǎng)上的資料非常多?,F(xiàn)在我把我自定義時(shí)鐘的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;// 標(biāo)記時(shí)分
private int itemHeight;// 每一行的高度
private int pHour, pMinute;// 初始化時(shí)顯示的時(shí)分時(shí)間
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
// 作用當(dāng)視圖完全加載進(jìn)來的時(shí)候再取控件的高度,否則取得值是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;
}
}
/**
* 設(shè)置分刻度盤
*
* @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);
}
/**
* 設(shè)置時(shí)刻度盤
*
* @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="設(shè)置時(shí)間"
android:textColor="@color/black"
android:textSize="24sp" />
<!-- 時(shí)間的相關(guān)設(shè)置 -->
<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="時(shí)"
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>
<!-- 設(shè)置時(shí)鐘的按鈕 -->
<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>
到這里基本上就完了。你看懂了嗎?好好研究吧!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用CountDownTimer類實(shí)現(xiàn)倒計(jì)時(shí)鬧鐘
- Android如何在App中啟動系統(tǒng)鬧鐘
- Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能
- 簡單實(shí)現(xiàn)Android鬧鐘功能
- Android自定義View 實(shí)現(xiàn)鬧鐘喚起播放鬧鐘鈴聲功能
- Android編程鬧鐘設(shè)置方法詳解
- Android鬧鐘設(shè)置的解決方案
- 簡單實(shí)現(xiàn)Android鬧鐘程序 附源碼
- Android手機(jī)鬧鐘服務(wù)AlarmManagerk開發(fā)案例
- android用鬧鐘定時(shí)做http請求推送的解決方案
相關(guān)文章
Android使用DisplayManager創(chuàng)建虛擬屏流程及原理解析
這篇文章主要介紹了Android使用DisplayManager創(chuàng)建虛擬屏流程及原理解析,DisplayManager提供了createVirtualDisplay接口,用于創(chuàng)建虛擬屏,虛擬屏可以把屏幕分出不同的區(qū)域,需要的朋友可以參考下2024-05-05
Android中APK簽名工具之jarsigner和apksigner詳解
這篇文章主要給大家介紹了關(guān)于Android中APK簽名工具之jarsigner和apksigner的相關(guān)資料,文中介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06
Android使用PhotoView實(shí)現(xiàn)圖片雙擊放大單擊退出效果
這篇文章主要為大家詳細(xì)介紹了Android使用PhotoView實(shí)現(xiàn)圖片雙擊放大單擊退出效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android使用MediaRecorder類進(jìn)行錄制視頻
這篇文章主要介紹了Android使用MediaRecorder類進(jìn)行錄制視頻的相關(guān)資料,需要的朋友可以參考下2015-10-10
android實(shí)現(xiàn)音樂播放器進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)音樂播放器進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
android開發(fā)修改狀態(tài)欄背景色和圖標(biāo)顏色的示例
本篇文章主要介紹了android開發(fā)修改狀態(tài)欄背景色和圖標(biāo)顏色的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
Android項(xiàng)目實(shí)戰(zhàn)之ListView懸浮頭部展現(xiàn)效果實(shí)現(xiàn)
這篇文章主要給大家介紹了Android項(xiàng)目實(shí)戰(zhàn)之ListView懸浮頭部展現(xiàn)效果實(shí)現(xiàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01
Android實(shí)現(xiàn)帶圖標(biāo)的列表對話框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶圖標(biāo)的列表對話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12

