Android倒计时功能的简单实现和改进

 更新时间:2016年9月20日 19:53  点击:1838
Android倒计时功能开发例子比较简单了,在网上一搜索有好几个这种方法,我来给各位整理一下,具体如下所示。

项目中经常会遇到找回密码的功能,现在找回密码一般都是用手机接收验证码,为了防止多次发送,一般需要设置一个发送间隔,比如60秒。为了让用户更加清楚的感受到这个间隔,于是就出现了倒计时功能.如下图:

点击之后,获取验证码的那个TextView或者Button变为不可点击,并且它的的text就要每秒变化一次,59,58,57…到最后一秒之后,text重新变为点击获取验证码,而且变为可点击.

看了一些前辈写的倒计时,都是用Handler和TimerTask来实现,然后我发现了一个更加简单的,Android自带的类来写这个功能.

接下来我就以一个简单的例子来实现这个功能。

1、activity_main.XML,为一个Button即可.

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
>

<Button
android:textSize=”25dp”
android:id=”@+id/btn_get”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:text=”点击获取验证码” />

</RelativeLayout>

2、MainActivity.java,既为重头戏,又极为简单.

package com.example.rr;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {

private Button mButton;//定义一个Button
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton=(Button) findViewById(R.id.btn_get);//←←获取按钮ID
//设置监听↓↓
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mButton.setClickable(false);
mButton.setTextColor(Color.parseColor(“#FF0000″));
MyTimer myTimer=new MyTimer(5000, 1000);//定义MyTimer的对象
myTimer.start();//启动倒计时
}});

}
private class MyTimer extends CountDownTimer{

//millisInFuture为你设置的此次倒计时的总时长,比如60秒就设置为60000
//countDownInterval为你设置的时间间隔,比如一般为1秒,根据需要自定义。
public MyTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub

}@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
mButton.setText(millisUntilFinished/1000+”秒后重新获取”);
}
//每过你规定的时间间隔做的操作↑↑
//倒计时结束时做的操作↓↓
@Override
public void onFinish() {
// TODO Auto-generated method stub
mButton.setClickable(true);
mButton.setTextColor(Color.parseColor(“#000000”));
mButton.setText(“点击获取验证码”);
}}}

在各个关键点我也做了标注,下面是我给大家录的gif.

timer

大家可以发现有2个问题:

1、在1秒的时候,会停顿大约两秒,这样就给了用户不太好的体验,还以为是手机卡了.为什么会出现这种问题呢?

2、点击Button时,出现的是数字4而不是数字5。

首先我们得知道这种方法的原理是什么,大家先看一下CountDownTimer的源码:

首先大家看一下这句: mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;

再看下下面的这句:  final long millisLeft = mStopTimeInFuture – SystemClock.elapsedRealtime();

(注意:SystemClock.elapsedRealtime()返回的是系统运行到现在的时间,每时每刻都在变化);

如果简单的进行数学计算的话,那么一开始mStopTimeInFuture是等于millisLeft的,但是不然,SystemClock.elapsedRealtime()返回的时间,以毫秒为单位,也就是说,从上面运行到下面,也消耗了些许时间,那么millisLeft就是小于5000的。

回到我们的Activity,我们在内部类的OnTick里写了什么?

mButton.setText(millisUntilFinished/1000+”秒后重新获取”);那么4900多除以1000后,返回的数值为4。

 解决方案:

                   在我们实例化MyTimer时,将5000改为6000.

 至于在1秒处停顿的情况,我们看一下最下面的if else 语句:

if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);

在 else if 语句处,当millisLeft<mCountdownInterval=1000,时,只进行停顿,而不调用OnTick方法,也就是说,我们运行程序时,millisLeft的数值从4900多~3900~2900~1900~900,900的时候,运行到这里,就会停顿,而不显示我们在OnTick写的代码.

           解决方案:

       重写CountDownTimer类。 

      然后, 

     1、在else if 中加OnTick(millisLeft);

2、删掉这个if  else 语句

    OK,我在重写类之后,将if else 语句改为下面的时候,依旧可以完成倒计时功能:

 if (millisLeft <= 0) {
onFinish();
} else {
onTick(millisLeft);
sendMessageDelayed(obtainMessage(MSG), 1000);
}

效果gif如下:

S 00_00_00-00_00_06

是不是写这个类的大牛想复杂了,还是我这个方法有问题呢?有知道的道友可以联系我~万分感谢!

PS:写这个文章浪费了快一下午,原因是网速不好,快写完了,保存草稿,然后出现意外,导致没保存,所以,,,,但是还是希望得到各位的建议和鼓励,谢谢!

下面我们来看一篇关于使用定制的ArrayAdapter制作ListView的Items的例子,希望这个例子能够给各位同学带来帮助的哦。

背景介绍

  对于现实世界中的商业移动应用来说,Android的ListView默认的界面外观不是非常有吸引力。它只是使用了内部的TextView控件,在每个ListView的行(Row)里面传递了一个简单的字符串而已。大多数应用,你会想要创建出富含图形界面和呈现给用户视觉体验良好的应用。幸运地是,ListView 是一个非常强大的控件,由于有可定制的item 布局的帮助,它可以被定制从而轻松地适应你的需求。在本文中,我将向你展示怎样创建一个定制的ListView  Item(有图标,自定义的header布局)以及怎样使用定制的ArrayAdapter将他们联系起来。我也会向你展示一些性能优化的小方法来优化你的ListView控件的内存占用。下面用一个例子来展示:

      图1. 天气图                            图2. 布局结构图
 
            

   一、项目布局

  在Eclipse中,创建一个新的Android项目,使用默认的Activity和main.xml布局文件。在main.xml文件中,声明一个ListView控件。

main.xml文件:
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3     xmlns:android=http://schemas.android.com/apk/res/android
 4     android:orientation="vertical"
 5     android:layout_width="fill_parent"
 6     android:layout_height="fill_parent"
 7     android:background="#FFFFFF">
 8    
 9      <ListView
10         android:id="@+id/listView1"
11         android:layout_width="fill_parent"
12         android:layout_height="fill_parent" />
13 </LinearLayout>

  上面的代码,使用了简单的线性布局方式,内部垂直排列。声明了一个ListView,占据整个父容器,他的android.layout_width和android.layout_width的属性都为fill_parent。ListView有一个唯一的id:listView1,在MainActivity中将用来引用ListView控件。

  为了创建定制的header,先在你的工程中创建一个新的xml布局文件:listview_header_row.xml,在里面声明一个TextView控件,属性值见下面的代码。将会创建出一个白色字体,蓝色背景的header。


 1 listview_header_row.xml文件:
 2 <?xml version="1.0" encoding="utf-8"?>
 3 <LinearLayout
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     android:orientation="horizontal"
 6     android:layout_width="fill_parent"
 7     android:layout_height="fill_parent">
 8        
 9      <TextView android:id="@+id/txtHeader"
10         android:layout_width="fill_parent"
11         android:layout_height="fill_parent"
12         android:gravity="center_vertical"
13         android:layout_alignParentTop="true"
14         android:layout_alignParentBottom="true"
15         android:textStyle="bold"
16         android:textSize="22dp"
17         android:textColor="#FFFFFF"
18         android:padding="10dp"
19         android:text="Weather Photos"
20         android:background="#336699" />
21
22 </LinearLayout>

  为了创建定制的ListView的行样式,先在你的工程中创建另一个xml布局文件:listview_item_row.xml。Android 会将这个文件的内容传递给每个ListView的item,你将可以自由的声明任何你想添加进里面的控件。本文中,我使用了一个ImageView来显示天气图标和一个TextView来显示该条item的主题。下面是listview_item_row.xml文件的代码:


 1 listview_item_row.xml文件:
 2 <?xml version="1.0" encoding="utf-8"?>
 3 <LinearLayout
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     android:orientation="horizontal"
 6     android:layout_width="fill_parent"
 7     android:layout_height="fill_parent"
 8     android:padding="10dp">
 9    
10      <ImageView android:id="@+id/imgIcon"
11         android:layout_width="wrap_content"
12         android:layout_height="fill_parent"
13         android:gravity="center_vertical"
14         android:layout_alignParentTop="true"
15         android:layout_alignParentBottom="true"
16         android:layout_marginRight="15dp"
17         android:layout_marginTop="5dp"
18         android:layout_marginBottom="5dp" />
19        
20      <TextView android:id="@+id/txtTitle"
21         android:layout_width="fill_parent"
22         android:layout_height="fill_parent"
23         android:gravity="center_vertical"
24         android:layout_alignParentTop="true"
25         android:layout_alignParentBottom="true"
26         android:textStyle="bold"
27         android:textSize="22dp"
28         android:textColor="#000000"
29         android:layout_marginTop="5dp"
30         android:layout_marginBottom="5dp" />
31        
32 </LinearLayout>

  本文中,我下载了一些32 X 32像素的PNG格式的图标。如果你愿意,你也可以使用你自己的图标。准备好你的图标,放到你工程的drawable-mdpi文件目录下。接下来,在工程中新建一个java类,命名为Weather.java,这个类将用于创建一个定制的ArrayAdapter来绑定对象到ListView中。下面是Weather.java文件的代码,它有两个简单的属性icon和title,一个普通的构造函数用于初始化属性。

二、项目程序开发

  为了方便大家理解,我将程序结构流程画出来:

图3.  重要对象关系结构

 1 Weather.java文件:
 2 public class Weather {
 3     public int icon;
 4     public String title;
 5     public Weather(){
 6         super();
 7     }
 8    
 9     public Weather(int icon, String title) {
10         super();
11         this.icon = icon;
12         this.title = title;
13     }
14 }

  注意,上面listview_item_row.xml文件有两个View,对应于Weather类的两个属性。Weather类的属性值将被显示到这两个View中。为了将这两个View连接起来,你需要创建一个定制的ArrayAdapter,它继承了Android的ArrayAdapter类,并重写了getView方法。添加一个新的java类到你的工程中,命名为WeatherAdapter,具体的实现代码如下:


 1 WeatherAdapter.java文件:
 2 public class WeatherAdapter extends ArrayAdapter<Weather>{
 3
 4     Context context;
 5     int layoutResourceId;   
 6     Weather data[] = null;
 7    
 8     public WeatherAdapter(Context context, int layoutResourceId, Weather[] data) {
 9         super(context, layoutResourceId, data);
10         this.layoutResourceId = layoutResourceId;
11         this.context = context;
12         this.data = data;
13     }
14
15     @Override
16     public View getView(int position, View convertView, ViewGroup parent) {
17         View row = convertView;
18         WeatherHolder holder = null;
19        
20         if(row == null)
21         {
22             LayoutInflater inflater = ((Activity)context).getLayoutInflater();
23             row = inflater.inflate(layoutResourceId, parent, false);
24            
25             holder = new WeatherHolder();
26             holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
27             holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
28            
29             row.setTag(holder);
30         }
31         else
32         {
33             holder = (WeatherHolder)row.getTag();
34         }
35        
36         Weather weather = data[position];
37         holder.txtTitle.setText(weather.title);
38         holder.imgIcon.setImageResource(weather.icon);
39        
40         return row;
41     }
42    
43     static class WeatherHolder
44     {
45         ImageView imgIcon;
46         TextView txtTitle;
47     }
48 }

  在上面的代码中,第一个比较重要的是类的构造函数有三个参数,第一个参数是Context对象(我们可以传递当前使用WeatherAdapter类的activity对象的引用,即MainActivity.this对象);第二个参数是resource的id(它是我们想用来呈现每个ListView的item的布局文件的id),在本文中我将传递我创建的listview_item_row.xml布局文件的id;第三个参数是一个Weather对象的数组,用于为Adapter适配器提供显示数据的数据源。

  ArrayAdapter的getView方法被重写了。这个方法将被ListView每个 item项调用来创建视图View,它们的属性是我们设置的。getView方法也使用了一个临时的holder类(在WeatherAdapter类内部声明的内部类),这个类将被用于缓存ImageView和TextView,以便它们能够被ListView中的每行重用,这也会为我们带来巨大的性能的提升,由于我们不断地访问两个相同的views(ImageView和TextView)的属性,我们不必为每个ListView的Item查找这两个控件。上面的代码也是用了Android内置的LayoutInflator来解析xml布局文件(用于动态加载xml布局文件,以便能够查找其中的内容)。

  最后一点代码是我们应用的MainActivity。里面,我们使用了所有上面声明的对象。下面是MainActivity.java文件的代码:

MainActivity.java文件:
 2 public class MainActivity extends Activity {
 3
 4     private ListView listView1;
 5
 6     @Override
 7     public void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.main);
10        
11         Weather weather_data[] = new Weather[]
12         {
13             new Weather(R.drawable.weather_cloudy, "Cloudy"),
14             new Weather(R.drawable.weather_showers, "Showers"),
15             new Weather(R.drawable.weather_snow, "Snow"),
16             new Weather(R.drawable.weather_storm, "Storm"),
17             new Weather(R.drawable.weather_sunny, "Sunny")
18         };
19        
20         WeatherAdapter adapter = new WeatherAdapter(this,
21                 R.layout.listview_item_row, weather_data);
22        
23        
24         listView1 = (ListView)findViewById(R.id.listView1);
25         
26         View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);
27         listView1.addHeaderView(header);
28        
29         listView1.setAdapter(adapter);
30     }
 
  MainActivity.java文件中有几个需要解释下的地方,以便你能更好的理解。首先,我们创建了一个Weather对象的数组,icon和title被作为参数传递给了它的构造函数;接下来,WeatherAdapter对象被创建,listview_item_row.xml文件的id和Weather对象数组被传递给了它的构造函数。再一次,我们使用了Android的LayoutInflator来解析listview_item_row.xml布局文件。通过ListView的addHeaderView方法设置ListView的header信息。最后,我们传递定制的Adapter给ListView的setAdapter方法。到现在就可以构建、运行工程了。如果一切实现正确,你会看到下面的内容。

      图2. 运行效果

  最近有一段时间没写东西了,真是罪过啊!翻译之中有不当之处在所难免,大家相互学习。尊重原创,尊重知识,相信分享的力量!

EditText可以实现当用户输入内容时自动变成金额输入框了,今天我们就一起来看一个安卓开发的EditText一秒变身金额输入框例子。

最近做的一个项目需要用到充值和提现金额,那么就需要在输入框中实现带小数点的金额数字,同时保证小数点后两位,于是在网上查了一些资料,实现了这样的功能。

首先,我们需要在布局中EditText中的属性里加上这样一句话:android:inputType=“numberDecimal”,表示输入的时候只能输入浮点型的数据。

自定义一个类,在这里写功能。

 代码如下 复制代码

import android.text.InputFilter;

import android.text.Spanned;
import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

* joy on 2015/12/17.

*

* 金额输入格式

*/

public class EditInputFilter implements InputFilter {

/**

* 最大数字,我们取int型最大值

*/

public static final int MAX_VALUE = 2147483647;

/**

* 小数点后的数字的位数

*/

public static final int PONTINT_LENGTH = 2;

Pattern p;

public EditInputFilter(){

p = Pattern.compile(“[0-9]*”);   //除数字外的其他的

}

/**

*  source    新输入的字符串

*  start    新输入的字符串起始下标,一般为0

*  end    新输入的字符串终点下标,一般为source长度-1

*  dest    输入之前文本框内容

*  dstart    原内容起始坐标,一般为0

*  dend    原内容终点坐标,一般为dest长度-1

*/

@Override

public CharSequence filter(CharSequence src, int start, int end,

Spanned dest, int dstart, int dend) {

String oldtext =  dest.toString();

System.out.println(oldtext);

//验证删除等按键

if (“”.equals(src.toString())) {

return null;

}

//验证非数字或者小数点的情况

Matcher m = p.matcher(src);

if(oldtext.contains(“.”)){

//已经存在小数点的情况下,只能输入数字

if(!m.matches()){

return null;

}

}else{

//未输入小数点的情况下,可以输入小数点和数字

if(!m.matches() && !src.equals(“.”) ){

return null;

}

}

//验证输入金额的大小

if(!src.toString().equals(“”)){

double dold = Double.parseDouble(oldtext+src.toString());

if(dold > MAX_VALUE){

return dest.subSequence(dstart, dend);

}else if(dold == MAX_VALUE){

if(src.toString().equals(“.”)){

return dest.subSequence(dstart, dend);

}

}

}

//验证小数位精度是否正确

if(oldtext.contains(“.”)){

int index = oldtext.indexOf(“.”);

int len = dend – index;

//小数位只能2位

if(len > PONTINT_LENGTH){

CharSequence newText = dest.subSequence(dstart, dend);

return newText;

}

}

return dest.subSequence(dstart, dend) +src.toString();

}

}

如何使用我们自定义的类呢,只需要在相应的Activity中定义EditText 控件edit_takeout_money;,然后:

InputFilter[] filters = { new EditInputFilter() };

edit_takeout_money.setFilters(filters);

就OK了

日期时间选择器在电脑中js有许多了,在android开发中也在库了,我们下面为各位整理了一些关于Android日期时间选择器的应用例子。

这里贴上一个Demo的源码,分享一下:

 代码如下 复制代码

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import com.bigkoo.pickerview.OptionsPopupWindow;
import com.bigkoo.pickerview.TimePopupWindow;
import com.bigkoo.pickerview.TimePopupWindow.OnTimeSelectListener;
import com.bigkoo.pickerview.TimePopupWindow.Type;
public class MainActivity extends Activity {

private TextView tvTime, tvOptions;
TimePopupWindow pwTime;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTime=(TextView) findViewById(R.id.tvTime);
//时间选择器
pwTime = new TimePopupWindow(this, Type.ALL);
//时间选择后回调
pwTime.setOnTimeSelectListener(new OnTimeSelectListener() {

@Override
public void onTimeSelect(Date date) {
tvTime.setText(getTime(date));
}
});
//弹出时间选择器
tvTime.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
pwTime.showAtLocation(tvTime, Gravity.BOTTOM, 0, 0,new Date());
}
});

}

public static String getTime(Date date) {
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm”);
return format.format(date);
}
}

 

当然只有上面一个源码文件肯定是不行的,分享这两个Demo的项目地址,大家可以去看一下。

 http://itlanbao.com/code/users/10000/20150911/Android-PickerView-master.rar

例子2

 代码如下 复制代码

自定义一个类:
/DateTimePicker/src/com/wwj/datetimepicker/DateTimePickDialogUtil.java

package com.wwj.datetimepicker;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;

/**
 * 日期时间选择控件 使用方法: private EditText inputDate;//需要设置的日期时间文本编辑框 private String
 * initDateTime="2012年9月3日 14:44",//初始日期时间值 在点击事件中使用:
 * inputDate.setOnClickListener(new OnClickListener() {
 *
 * @Override public void onClick(View v) { DateTimePickDialogUtil
 *           dateTimePicKDialog=new
 *           DateTimePickDialogUtil(SinvestigateActivity.this,initDateTime);
 *           dateTimePicKDialog.dateTimePicKDialog(inputDate);
 *
 *           } });
 *
 * @author
 */
public class DateTimePickDialogUtil implements OnDateChangedListener,
  OnTimeChangedListener {
 private DatePicker datePicker;
 private TimePicker timePicker;
 private AlertDialog ad;
 private String dateTime;
 private String initDateTime;
 private Activity activity;

 /**
  * 日期时间弹出选择框构造函数
  *
  * @param activity
  *            :调用的父activity
  * @param initDateTime
  *            初始日期时间值,作为弹出窗口的标题和日期时间初始值
  */
 public DateTimePickDialogUtil(Activity activity, String initDateTime) {
  this.activity = activity;
  this.initDateTime = initDateTime;

 }

 public void init(DatePicker datePicker, TimePicker timePicker) {
  Calendar calendar = Calendar.getInstance();
  if (!(null == initDateTime || "".equals(initDateTime))) {
   calendar = this.getCalendarByInintData(initDateTime);
  } else {
   initDateTime = calendar.get(Calendar.YEAR) + "年"
     + calendar.get(Calendar.MONTH) + "月"
     + calendar.get(Calendar.DAY_OF_MONTH) + "日 "
     + calendar.get(Calendar.HOUR_OF_DAY) + ":"
     + calendar.get(Calendar.MINUTE);
  }

  datePicker.init(calendar.get(Calendar.YEAR),
    calendar.get(Calendar.MONTH),
    calendar.get(Calendar.DAY_OF_MONTH), this);
  timePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
  timePicker.setCurrentMinute(calendar.get(Calendar.MINUTE));
 }

 /**
  * 弹出日期时间选择框方法
  *
  * @param inputDate
  *            :为需要设置的日期时间文本编辑框
  * @return
  */
 public AlertDialog dateTimePicKDialog(final EditText inputDate) {
  LinearLayout dateTimeLayout = (LinearLayout) activity
    .getLayoutInflater().inflate(R.layout.common_datetime, null);
  datePicker = (DatePicker) dateTimeLayout.findViewById(R.id.datepicker);
  timePicker = (TimePicker) dateTimeLayout.findViewById(R.id.timepicker);
  init(datePicker, timePicker);
  timePicker.setIs24HourView(true);
  timePicker.setOnTimeChangedListener(this);

  ad = new AlertDialog.Builder(activity)
    .setTitle(initDateTime)
    .setView(dateTimeLayout)
    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int whichButton) {
      inputDate.setText(dateTime);
     }
    })
    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int whichButton) {
      inputDate.setText("");
     }
    }).show();

  onDateChanged(null, 0, 0, 0);
  return ad;
 }

 public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
  onDateChanged(null, 0, 0, 0);
 }

 public void onDateChanged(DatePicker view, int year, int monthOfYear,
   int dayOfMonth) {
  // 获得日历实例
  Calendar calendar = Calendar.getInstance();

  calendar.set(datePicker.getYear(), datePicker.getMonth(),
    datePicker.getDayOfMonth(), timePicker.getCurrentHour(),
    timePicker.getCurrentMinute());
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");

  dateTime = sdf.format(calendar.getTime());
  ad.setTitle(dateTime);
 }

 /**
  * 实现将初始日期时间2012年07月02日 16:45 拆分成年 月 日 时 分 秒,并赋值给calendar
  *
  * @param initDateTime
  *            初始日期时间值 字符串型
  * @return Calendar
  */
 private Calendar getCalendarByInintData(String initDateTime) {
  Calendar calendar = Calendar.getInstance();

  // 将初始日期时间2012年07月02日 16:45 拆分成年 月 日 时 分 秒
  String date = spliteString(initDateTime, "日", "index", "front"); // 日期
  String time = spliteString(initDateTime, "日", "index", "back"); // 时间

  String yearStr = spliteString(date, "年", "index", "front"); // 年份
  String monthAndDay = spliteString(date, "年", "index", "back"); // 月日

  String monthStr = spliteString(monthAndDay, "月", "index", "front"); // 月
  String dayStr = spliteString(monthAndDay, "月", "index", "back"); // 日

  String hourStr = spliteString(time, ":", "index", "front"); // 时
  String minuteStr = spliteString(time, ":", "index", "back"); // 分

  int currentYear = Integer.valueOf(yearStr.trim()).intValue();
  int currentMonth = Integer.valueOf(monthStr.trim()).intValue() - 1;
  int currentDay = Integer.valueOf(dayStr.trim()).intValue();
  int currentHour = Integer.valueOf(hourStr.trim()).intValue();
  int currentMinute = Integer.valueOf(minuteStr.trim()).intValue();

  calendar.set(currentYear, currentMonth, currentDay, currentHour,
    currentMinute);
  return calendar;
 }

 /**
  * 截取子串
  *
  * @param srcStr
  *            源串
  * @param pattern
  *            匹配模式
  * @param indexOrLast
  * @param frontOrBack
  * @return
  */
 public static String spliteString(String srcStr, String pattern,
   String indexOrLast, String frontOrBack) {
  String result = "";
  int loc = -1;
  if (indexOrLast.equalsIgnoreCase("index")) {
   loc = srcStr.indexOf(pattern); // 取得字符串第一次出现的位置
  } else {
   loc = srcStr.lastIndexOf(pattern); // 最后一个匹配串的位置
  }
  if (frontOrBack.equalsIgnoreCase("front")) {
   if (loc != -1)
    result = srcStr.substring(0, loc); // 截取子串
  } else {
   if (loc != -1)
    result = srcStr.substring(loc + 1, srcStr.length()); // 截取子串
  }
  return result;
 }

}


/DateTimePicker/src/com/wwj/datetimepicker/DateTimePickerActivity.java

package com.wwj.datetimepicker;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;

/**
 * 时间拾取器界面
 *
 * @author wwj_748
 *
 */
public class DateTimePickerActivity extends Activity {
 /** Called when the activity is first created. */
 private EditText startDateTime;
 private EditText endDateTime;

 private String initStartDateTime = "2013年9月3日 14:44"; // 初始化开始时间
 private String initEndDateTime = "2014年8月23日 17:44"; // 初始化结束时间

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // 两个输入框
  startDateTime = (EditText) findViewById(R.id.inputDate);
  endDateTime = (EditText) findViewById(R.id.inputDate2);

  startDateTime.setText(initStartDateTime);
  endDateTime.setText(initEndDateTime);

  startDateTime.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {

    DateTimePickDialogUtil dateTimePicKDialog = new DateTimePickDialogUtil(
      DateTimePickerActivity.this, initEndDateTime);
    dateTimePicKDialog.dateTimePicKDialog(startDateTime);

   }
  });

  endDateTime.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    DateTimePickDialogUtil dateTimePicKDialog = new DateTimePickDialogUtil(
      DateTimePickerActivity.this, initEndDateTime);
    dateTimePicKDialog.dateTimePicKDialog(endDateTime);
   }
  });
 }
}

自定义界面:
/DateTimePicker/res/layout/common_datetime.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="fill_parent"
    android:orientation="vertical" >

    <DatePicker
        android:id="@+id/datepicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <TimePicker
        android:id="@+id/timepicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

GestureDetector在android开发中使用到比较的多了,我们下面一起来看一篇关于安卓开发使用GestureDetector手势滑动界面的例子,具体细节如下所示.

用惯了苹果的人都知道在在APP中只需要手指左右滑动就可以进行页面的转换,但是在Android中大部分软件还只是使用返回键来进行界面的更替,其实Android很早很早以前就支持手势去更新操作,只是很多APP中没有使用到GestureDetector,下面就简单说说通过GestureDetector来进行界面的更替,下面只给出关键代码,直接使用即可。


GestureDetector  detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {//
@Override
public boolean onDown(MotionEvent e) {
return false;
}
 
@Override
public void onShowPress(MotionEvent e) {
 
}
 
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
 
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
 
@Override
public void onLongPress(MotionEvent e) {
 
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (e1.getX() - e2.getX() > 120) {//向左滑动,在这里可以进行界面间的更新,你想怎么干就怎么干
Intent intent = new Intent();
intent.setClass(MainActivity.this, Two.class);
startActivity(intent);
return true;
} else if (e1.getX() - e2.getX() < -120) {//向右滑动
MainActivity.this.finish();
return true;
}
return false;
}
});
 
@Override
public boolean onTouchEvent(MotionEvent event) {//一定要在activity中重写onTouchEvent方法才能使手势生效
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
 
上面是在正常情况下的滑动,当你在ListView等本身带有滑动的控件使用手势绝对会冲突,下面只给出最简单最粗暴的解决方式—— 改变系统的 onTouchEvent 事件的顺序,重写dispatchTouchEvent方法

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
 this.detector.onTouchEvent(ev);
 return super.dispatchTouchEvent(ev);
}

以上就是通过GestureDetector手势来进行界面间的转换,对动画研究透彻的童鞋可以在界面交替时加上动画效果!GestureDetector还有很多功能,有兴趣的可以继续研究

[!--infotagslink--]

相关文章

  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • vue实现同时设置多个倒计时

    这篇文章主要为大家详细介绍了vue实现同时设置多个倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-05-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • jQuery+slidereveal实现的面板滑动侧边展出效果

    我们借助一款jQuery插件:slidereveal.js,可以使用它控制面板左右侧滑出与隐藏等效果,项目地址:https://github.com/nnattawat/slideReveal。如何使用首先在页面中加载jquery库文件和slidereveal.js插件。复制代码 代码如...2015-03-15
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • PHP+jQuery翻板抽奖功能实现

    翻板抽奖的实现流程:前端页面提供6个方块,用数字1-6依次表示6个不同的方块,当抽奖者点击6个方块中的某一块时,方块翻转到背面,显示抽奖中奖信息。看似简单的一个操作过程,却包含着WEB技术的很多知识面,所以本文的读者应该熟...2015-10-21
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • SQLMAP结合Meterpreter实现注入渗透返回shell

    sqlmap 是一个自动SQL 射入工具。它是可胜任执行一个广泛的数据库管理系统后端指印, 检索遥远的DBMS 数据库等,下面我们来看一个学习例子。 自己搭建一个PHP+MYSQ...2016-11-25
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • PHP实现今天是星期几的几种写法

    复制代码 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ echo "今天是星期一"; }else if( $da == "2" ){ echo "今天是星期二"; }else if( $da == "3" ){ echo "今天是星期三"; }else if( $da == "4"...2013-10-04
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15