在学校没写过blog,寒假的首次更新就献给Android的小玩意吧。
这篇文章主要讲的是Android倒计时程序的实现,先看看最终效果:
习惯性的全局大色块(骚气蓝色……),功能提供了开始计时停止计时和重置,满足正常的需求。
Q:通过这篇文章可以学到什么?
A:
1. 基本布局设计
2. Time计时器的使用
3. 暂时没了吧……
下面的工作分为两部分:UI&逻辑
一 .UI设计
不是学UI出身,会使用Photoshop,最近迷上Material Design,这就是我对自己的定义(傻笑脸),设计UI也是一个很费脑筋的事情。经过百般周折,如下的UI布局诞生了。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context="com.surine.counttime.MainActivity">
<TextView
android:text="点击标题\n输入时间"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:textColor="#fff"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/time"/>
<EditText
android:layout_height="40dp"
android:layout_width="match_parent"
android:inputType="number"
android:ems="10"
android:id="@+id/input"
android:hint="点此设置时间"
android:textColor="#fff"
android:background="@color/colorPrimary"
android:gravity="center"
android:textColorHint="#fff"
android:textCursorDrawable="@null"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"/>
<Button
android:text="开始"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="14dp"
android:id="@+id/start"
android:textColor="#fff"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_alignParentBottom="true"
android:layout_toStartOf="@+id/end"/>
<Button
android:text="重置"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/reset"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_alignBaseline="@+id/end"
android:layout_alignBottom="@+id/end"
android:layout_toEndOf="@+id/end"/>
<Button
android:text="停止"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/end"
android:textColor="#fff"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_alignBaseline="@+id/start"
android:layout_alignBottom="@+id/start"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
全局无边界设计,沉浸的还是可以得,惊艳的大字体让我想到了Windows Phone,这里处理了一下edittext的光标和背景,还有添加了button的主题(安卓斯丢丢的伟大功能,一键设置主题),布局就是这样,下面是逻辑。
二 .逻辑设计
首先我们进行初始化工作
在MainAcitivity里添加相关的控件对象
private EditText input; //输入框对象
private TextView time; //中间的文字对象
private Button start,end,reset; //三个按钮
在onCreate()方法里添加初始化方法init();
init()内容如下:
private void init() {
input= (EditText) findViewById(R.id.input);
time= (TextView) findViewById(R.id.time);
start= (Button) findViewById(R.id.start);
end= (Button) findViewById(R.id.end);
reset= (Button) findViewById(R.id.reset);
}
init()完成了控件的实例化,下面应该设置上监听器,在onCreate()方法里添加addListener()方法,内容如下
private void addListener() {
input.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if(!input.getText().toString().equals(""))
the_number_time= Integer.parseInt(input.getText().toString()); //输入完成之后获取字符并强转
}
});
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
input.setVisibility(View.GONE); //设置输入框的可见性
start(); //声明的开始方法
}
});
end.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
end();//声明的结束方法
}
});
reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
reset();//声明的重置方法
}
});
}
1.其中edittext添加TextWatcher监听器监听文字变化,首先需要声明一个int存放输入的数字,然后在监听器里获取这个数字。
2.其次在按钮监听器里声明相应的方法(先生成空白方法)。
初始化和监听已经完成,我们将使用Timer来完成计时操作,声明Time和Timertask
private Timer timer =null;
private TimerTask task=null;
下面完成start()方法
private void start() {
//屏蔽多启动
start.setClickable(false);
timer = new Timer();
//启动定时任务
task=new TimerTask() {
@Override
public void run() {
Message message = mHandler.obtainMessage();
//计时器自减
the_number_time--;
message.arg1 = the_number_time;
//发送数据
mHandler.sendMessage(message);
}
};
//启动计时器(1s)
timer.schedule(task,1000);
}
子线程发送信息更新UI的写法,在一开始屏蔽了start的按键(为了防止多次启动计时器),然后设计定时任务,启动定时任务,发送任务信息给Handler
Handler如下
private Handler mHandler =new Handler(){
public void handleMessage(Message msg)
{
if(msg.arg1>=0) {
time.setText(msg.arg1 + "");
start();
}
else{
time.setText("分秒流逝……");
end();
}
}
};
接受msg数据,为了防止一直计时,在计时器等于0时,直接end()掉。
下面是end()方法。
private void end() {
start.setClickable(true); //解锁开始键
input.setVisibility(View.VISIBLE); //显示输入框
timer.cancel(); //停止计时器
}
下面是reset()
private void reset() {
the_number_time=0; //数据重置
time.setText("计时器重置为0"); //文字提示
input.setText("0"); //输入框重置
}
好了,所有的代码就是这样,运行起来效果还是可以的,至少目前发现的bug全部解决完了,如果哪个宝宝发现bug可以戳我。
美图一张: