天天看點

android 弧形齒輪控件,Android學習筆記(一)之仿正點鬧鐘時間齒輪滑動的效果

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

android 弧形齒輪控件,Android學習筆記(一)之仿正點鬧鐘時間齒輪滑動的效果

首先是MainActivity的布局檔案,這個布局檔案非常簡單,就是一個Button:activity_main.xml檔案,代碼如下:

android:id="@+id/ll_timeset"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ffffff"

android:orientation="vertical" >

android:id="@+id/btn"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:text="時間設定"

android:textSize="24sp" />

緊接着就是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;

}

}

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

}

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代碼如下:

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="#efefef"

android:orientation="vertical" >

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" />

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

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical" >

android:layout_width="30dp"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:background="@drawable/wheel_arrow_up" />

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

android:id="@+id/ll01"

android:layout_width="50dp"

android:layout_height="wrap_content"

android:gravity="center"

android:orientation="horizontal"

android:paddingTop="5dp" >

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" />

android:layout_width="30dp"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:background="@drawable/wheel_arrow_down" />

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" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical" >

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" />

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

android:id="@+id/ll02"

android:layout_width="50dp"

android:layout_height="wrap_content"

android:gravity="center"

android:paddingTop="5dp" >

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" />

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" />

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" />

android:layout_width="fill_parent"

android:layout_height="50dp" >

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" />

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" />

為了讓自定義的Dialog的樣式更好看,這裡還需要自定義樣式的Style,Style的代碼如下;

@null

true

@color/light_grey

true

@null

到這裡基本上就完了。你看懂了嗎?好好研究吧!

求源碼,請關注微信訂閱号:smart_android,微信名:非著名程式員,關注成功後,給微信号發送您的郵箱,源碼就會發到您的郵箱裡。發送格式:發送内容+您的郵箱(内容即為你要的源碼内容)

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。