看到正点闹钟上的设置时间的滑动效果非常好看,自己就想做一个那样的,在网上就开始搜资料了,看到网上有的齿轮效果的代码非常多,也非常难懂,我就决定自己研究一下,现在我就把我的研究成果分享给大家。我研究的这个效果出来了,而且代码也非常简单,通俗易懂。效果图如下:
首先是MainActivity的布局文件,这个布局文件非常简单,就是一个Button:activity_main.xml文件,代码如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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的代码,代码如下:
- packagenet.loonggg.test;
- importnet.loonggg.view.CustomerDateDialog;
- importnet.loonggg.view.CustomerDateDialog.DateDialogListener;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.text.format.DateFormat;
- importandroid.view.View;
- importandroid.view.Window;
- importandroid.widget.Button;
- importandroid.widget.Toast;
- publicclassMainActivityextendsActivity{
- privateinth,m;
- privateCustomerDateDialogdialog;
- privateButtonbtn;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- btn=(Button)findViewById(R.id.btn);
- btn.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- Stringdatetime=DateFormat.format("kk:mm",
- System.currentTimeMillis()).toString();
- String[]strs=datetime.split(":");
- h=Integer.parseInt(strs[0]);
- m=Integer.parseInt(strs[1]);
- dialog=newCustomerDateDialog(MainActivity.this,h,m);
- dialog.show();
- dialog.setOnDateDialogListener(newDateDialogListener(){
- @Override
- publicvoidgetDate(){
- Toast.makeText(
- MainActivity.this,
- "时间是:"+dialog.getSettingHour()+"点"
- +dialog.getSettingMinute()+"分",
- Toast.LENGTH_LONG).show();
- }
- });
- }
- });
- }
- }
再就是我自定义了一个时钟的Dialog,自定义Dialog也非常简单,自己可以学一下,这方面网上的资料非常多。现在我把我自定义时钟的Dialog的代码分享一下,代码如下:
- packagenet.loonggg.view;
- importnet.loonggg.test.R;
- importandroid.annotation.SuppressLint;
- importandroid.app.Dialog;
- importandroid.content.Context;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.view.LayoutInflater;
- importandroid.view.MotionEvent;
- importandroid.view.View;
- importandroid.view.View.OnTouchListener;
- importandroid.view.ViewTreeObserver;
- importandroid.view.ViewTreeObserver.OnGlobalLayoutListener;
- importandroid.widget.Button;
- importandroid.widget.LinearLayout;
- importandroid.widget.ScrollView;
- importandroid.widget.TextView;
- @SuppressLint("HandlerLeak")
- publicclassCustomerDateDialogextendsDialog{
- privateViewcustomView;
- privateButtonsetBtn;
- privateButtoncancleBtn;
- privateTextViewarrow_up;
- privateTextViewtv01,tv02;
- privateScrollViewsv01,sv02;
- privateLinearLayoutllTimeWheel;
- privateDateDialogListenerlistener;
- privateintlastY;
- privateintflag;//标记时分
- privateintitemHeight;//每一行的高度
- privateintpHour,pMinute;//初始化时显示的时分时间
- privateintsetHour,setMinute;
- publicCustomerDateDialog(Contextcontext,inthour,intminute){
- super(context,R.style.CustomerDateDialog);
- customView=LayoutInflater.from(context).inflate(R.layout.time_wheel,
- null);
- init(context,hour,minute);
- }
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- this.setContentView(customView);
- }
- privatevoidinit(Contextcontext,finalinthour,finalintminute){
- 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);
- finalViewTreeObserverobserver=sv01.getViewTreeObserver();//observer
- //作用当视图完全加载进来的时候再取控件的高度,否则取得值是0
- observer.addOnGlobalLayoutListener(newOnGlobalLayoutListener(){
- @SuppressWarnings("deprecation")
- publicvoidonGlobalLayout(){
- inttvHeight=tv02.getHeight();
- itemHeight=tvHeight/180;
- if(sv01.getViewTreeObserver().isAlive()){
- sv01.getViewTreeObserver().removeGlobalOnLayoutListener(
- this);
- }
- LinearLayout.LayoutParamsparams=newLinearLayout.LayoutParams(
- LinearLayout.LayoutParams.FILL_PARENT,(itemHeight*3)
- +arrow_up.getHeight()*2);
- llTimeWheel.setLayoutParams(params);
- sv01.setLayoutParams(newLinearLayout.LayoutParams(tv02
- .getWidth(),(itemHeight*3)));
- sv02.setLayoutParams(newLinearLayout.LayoutParams(tv02
- .getWidth(),(itemHeight*3)));
- sv01.scrollTo(0,(pHour+23)*itemHeight);
- sv02.scrollTo(0,(pMinute+59)*itemHeight);
- }
- });
- setBtn.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- getSettingDate();
- CustomerDateDialog.this.cancel();
- }
- });
- cancleBtn.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- CustomerDateDialog.this.cancel();
- }
- });
- }
- privateOnTouchListenertListener=newOnTouchListener(){
- publicbooleanonTouch(Viewv,MotionEventevent){
- if(v==sv01){
- flag=1;
- }else{
- flag=2;
- }
- if(event.getAction()==MotionEvent.ACTION_UP){
- finalScrollViewsv=(ScrollView)v;
- lastY=sv.getScrollY();
- System.out.println("lastY"+lastY);
- handler.sendMessageDelayed(handler.obtainMessage(0,v),50);
- }
- returnfalse;
- }
- };
- privateHandlerhandler=newHandler(){
- @SuppressLint("HandlerLeak")
- publicvoidhandleMessage(android.os.Messagemsg){
- ScrollViewsv=(ScrollView)msg.obj;
- if(msg.what==0){
- if(lastY==sv.getScrollY()){
- intnum=lastY/itemHeight;
- intover=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毫秒再判断
- }
- }
- };
- };
- privatevoidlocationTo(intposition,ScrollViewscrollview,intflag){
- switch(flag){
- case1:
- intmPosition=0;
- if(position<=23*itemHeight){
- mPosition=position+24*itemHeight;
- scrollview.scrollTo(0,mPosition);
- }elseif(position>=48*itemHeight){
- mPosition=position-24*itemHeight;
- scrollview.scrollTo(0,mPosition);
- }else{
- mPosition=position;
- scrollview.smoothScrollTo(0,position);
- }
- setHour=(mPosition/itemHeight-23)%24;
- break;
- case2:
- inthPosition=0;
- if(position<=57*itemHeight){
- hPosition=position+60*itemHeight;
- scrollview.scrollTo(0,hPosition);
- }elseif(position>=120*itemHeight){
- hPosition=position-60*itemHeight;
- scrollview.scrollTo(0,hPosition);
- }else{
- hPosition=position;
- scrollview.smoothScrollTo(0,position);
- }
- setMinute=(hPosition/itemHeight)%60+1;
- break;
- }
- }
- /**
- *设置分刻度盘
- *
- *@paramtv
- */
- privatevoidsetMinuteDial(TextViewtv){
- StringBufferbuff=newStringBuffer();
- for(inti=0;i<3;i++){
- for(intj=0;j<60;j++){
- if(j<=9){
- buff.append("0"+j);
- }else{
- buff.append(j+"");
- }
- }
- }
- tv.setText(buff);
- }
- /**
- *设置时刻度盘
- *
- *@paramtv
- */
- privatevoidsetHourDial(TextViewtv){
- StringBufferbuff=newStringBuffer();
- for(inti=0;i<3;i++){
- for(intj=0;j<24;j++){
- if(j<=9){
- buff.append("0"+j);
- }else{
- buff.append(j+"");
- }
- }
- }
- tv.setText(buff);
- }
- publicvoidsetpHour(intpHour){
- this.pHour=pHour;
- }
- publicvoidsetpMinute(intpMinute){
- this.pMinute=pMinute;
- }
- publicvoidsetOnDateDialogListener(DateDialogListenerlistener){
- this.listener=listener;
- }
- publicinterfaceDateDialogListener{
- voidgetDate();
- }
- publicvoidgetSettingDate(){
- if(listener!=null){
- listener.getDate();
- }
- }
- publicintgetSettingHour(){
- returnsetHour;
- }
- publicintgetSettingMinute(){
- returnsetMinute;
- }
- }
这里光有java代码还不够,还有自定义Dialog的布局文件,time_wheel.xml代码如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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的代码如下;
- <stylename="CustomerDateDialog"parent="@android:Theme.Dialog">
- <itemname="android:windowFrame">@null</item>
- <itemname="android:windowNoTitle">true</item>
- <itemname="android:windowBackground">@color/light_grey</item>
- <itemname="android:windowIsFloating">true</item>
- <itemname="android:windowContentOverlay">@null</item>
- </style>
到这里基本上就完了。你看懂了吗?好好研究吧!