รอบนี้มาต่อกันด้วยบทความเรื่อง Timer หรือตัวนับเวลากัน เพราะมีผู้ที่หลงเข้ามาอ่านหลายคนอยากทำตัวจับเวลา โดยเฉพาะกับแอพจำพวก Quiz หรือตอบปัญหาที่ต้องการนับเวลาถอยหลังในการตอบคำถามแต่ละข้อ
ในการนับเวลาถอยหลังจะใช้ Thread หรือ Handler ก็ได้ แต่ว่าก็มีคลาส CountDownTimer ให้ใช้อยู่แล้ว ไม่ต้องเขียนเอง
สำหรับการใช้งานคลาสดังกล่าว จะอยู่ในรูปง่ายๆดังนี้
สำหรับคลาสนี้จะเป็นว่ามีการกำหนดค่าให้สองตัว ตัวแรกคือเวลาทั้งหมดที่ต้องการให้นับ [10000] และเวลาที่ต้องการให้นับในแต่ละช่วง [1000] โดยทั้งสองค่านี้จะมีหน่วยเป็นมิลลิวินาที (ms)
สำหรับการใช้งานคลาสดังกล่าว จะอยู่ในรูปง่ายๆดังนี้
CountDownTimer cdt = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
// Tick
}
public void onFinish() {
// Finish
}
}.start();
สำหรับคลาสนี้จะเป็นว่ามีการกำหนดค่าให้สองตัว ตัวแรกคือเวลาทั้งหมดที่ต้องการให้นับ [10000] และเวลาที่ต้องการให้นับในแต่ละช่วง [1000] โดยทั้งสองค่านี้จะมีหน่วยเป็นมิลลิวินาที (ms)
จากตัวอย่างที่ได้กำหนดค่าไว้เป็น 10000 กับ 1000 เมื่อคลาสนี้ทำงาน จะนับเวลาทั้งหมด 10 วินาที โดยที่ทุกๆ 1 วินาที ฟังก์ชัน onTick จะทำงาน และเมื่อนับครบ 10 วินาที ฟังก์ชัน onFinish จะทำงาน
หลักการง่ายๆเลย ทุกๆ 1 วินาทีจะทำอะไร ครบ 10 วินาทีแล้วอยากจะให้ทำอะไร
ดูที่ฟังก์ชัน onTick มีตัวแปรมาด้วยเป็นตัวแปร Long ซึ่งตัวแปรตัวนี้เอาไว้ดูได้ว่าเหลือเวลาอีกกี่มิลลิวินาที ดังนั้นก็เอาตัวแปรนี้มาแปลงเป็นวินาทีก็จะได้ว่า ตอนนี้เหลือเวลาอีกกี่วินาที เอาไปแสดงยังไงก็แล้วแต่ และเมื่อนับครบแล้วหรือ onFinish ก็หยุดการนับ
มาดูตัวอย่างการใช้งานจริงคร่าวๆ กันเลยดีกว่า ในตัวอย่างนี้จะให้มีปุ่ม Toggle Button แทน Button เพราะอยากให้กดเพื่อจับเวลาและหยุดจับเวลาได้ ก็เลยใช้ Toggle Button ไปเลย จะได้สะดวกดี สำหรับภาพที่ใช้กับ Toggle Button ก็มี 4 ภาพดังนี้
โดยนำมา Custom Toggle Button ให้ดูเหมาะสมกันหน่อย
button_start.xml
main.xml
สำหรับ Progress Bar ในโค๊ด Java จะใช้คำสั่งซ่อนเอาไว้ก่อน จะแสดงก็ต่อเมื่อกดจับเวลาเท่านั้น เมื่อจับเวลาเสร็จก็ซ่อนไว้ เพื่อให้ดูเหมือนว่ากดจับเวลาแล้วมีแถบวิ่งเพื่อให้รู้ว่าจับเวลา
Main.java
สำหรับตัวอย่างนี้ก็ไม่ยากมากนัก กดเพื่อนับเวลาถอยหลัง 10 วินาที โดยแสดงเวลาที่เหลืออยู่เป็นตัวเลขทศนิยม 1 หลัก อยู่ตรงกลางจอที่มี Progress Bar แสดงอยู่รอบตัวเลข ซึ่งจะแสดงเมื่อกดจับเวลาเท่านั้น
ดูที่ฟังก์ชัน onTick มีตัวแปรมาด้วยเป็นตัวแปร Long ซึ่งตัวแปรตัวนี้เอาไว้ดูได้ว่าเหลือเวลาอีกกี่มิลลิวินาที ดังนั้นก็เอาตัวแปรนี้มาแปลงเป็นวินาทีก็จะได้ว่า ตอนนี้เหลือเวลาอีกกี่วินาที เอาไปแสดงยังไงก็แล้วแต่ และเมื่อนับครบแล้วหรือ onFinish ก็หยุดการนับ
มาดูตัวอย่างการใช้งานจริงคร่าวๆ กันเลยดีกว่า ในตัวอย่างนี้จะให้มีปุ่ม Toggle Button แทน Button เพราะอยากให้กดเพื่อจับเวลาและหยุดจับเวลาได้ ก็เลยใช้ Toggle Button ไปเลย จะได้สะดวกดี สำหรับภาพที่ใช้กับ Toggle Button ก็มี 4 ภาพดังนี้
โดยนำมา Custom Toggle Button ให้ดูเหมาะสมกันหน่อย
button_start.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:state_checked="false"
android:drawable="@drawable/button_start_pressed" />
<item android:state_pressed="false" android:state_checked="false"
android:drawable="@drawable/button_start_normal" />
<item android:state_pressed="true" android:state_checked="true"
android:drawable="@drawable/button_stop_pressed" />
<item android:state_pressed="false" android:state_checked="true"
android:drawable="@drawable/button_stop_normal" />
</selector>
main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Main" >
<ToggleButton
android:id="@+id/btnCount"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="@+id/pbTimer"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginTop="10dp"
android:background="@drawable/button_start"
android:textOn=""
android:textOff="" />
<ProgressBar
android:id="@+id/pbTimer"
style="?android:attr/progressBarStyleLarge"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/tvTimer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="0"
android:textSize="40sp" />
</RelativeLayout>
สำหรับ Progress Bar ในโค๊ด Java จะใช้คำสั่งซ่อนเอาไว้ก่อน จะแสดงก็ต่อเมื่อกดจับเวลาเท่านั้น เมื่อจับเวลาเสร็จก็ซ่อนไว้ เพื่อให้ดูเหมือนว่ากดจับเวลาแล้วมีแถบวิ่งเพื่อให้รู้ว่าจับเวลา
Main.java
package app.akexorcist.countdowntimer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Activity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ToggleButton;
public class Main extends Activity {
CountDownTimer cdt;
TextView tvTimer;
ToggleButton btnCount;
ProgressBar pbTimer;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tvTimer = (TextView)findViewById(R.id.tvTimer);
pbTimer = (ProgressBar)findViewById(R.id.pbTimer);
pbTimer.setVisibility(View.INVISIBLE);
btnCount = (ToggleButton)findViewById(R.id.btnCount);
btnCount.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton view
, boolean isChecked) {
if(isChecked) {
pbTimer.setVisibility(View.VISIBLE);
cdt = new CountDownTimer(10000, 50) {
public void onTick(long millisUntilFinished) {
String strTime = String.format("%.1f"
, (double)millisUntilFinished / 1000);
tvTimer.setText(String.valueOf(strTime));
}
public void onFinish() {
tvTimer.setText("0");
btnCount.setChecked(false);
pbTimer.setVisibility(View.INVISIBLE);
}
}.start();
} else {
cdt.cancel();
tvTimer.setText("0");
pbTimer.setVisibility(View.INVISIBLE);
}
}
});
}
}
และเมื่อกดเริ่มนับเวลาถอยหลัง ปุ่ม Toggle Button ก็จะเปลี่ยนเป็น Off หรือเรียกอีกอย่างว่า False ก็จะให้แสดงภาพปุ่มหยุดที่ได้กำหนดไว้ ถ้านับเวลาจนครบแล้วก็จะให้แสดงเลข 0 ทำการซ่อน Progress Bar และปุ่ม Toggle Button เป็น On เพื่อให้ผู้ใช้ได้กดจับเวลาใหม่ได้
แต่กรณีที่ผู้ใช้กดปุ่มหยุดกลางคัน ก็จะให้หยุดนับเวลาถอยหลัง ซ่อน Progress Bar และแสดงข้อความใน Text View เป็น 0 ทันที