ProgressBar (Horizontal) - Android Widgets Example |
ProgressBar (Horizontal) - Android Form Widgets เป็น Widget ที่ไว้สำหรับการสร้างปุ่ม ProgressBar แบบ Horizontal (แนวนอน) โดจะแสดงสถานะการทำงาน รวมทั้งตัวเลขเปอร์เซ็นต์ กำลังทำงาน โดยข้อมูลเหล่านี้จะทำควณจากการทำงานจริงในขณะนั้น ๆ ซึ่งขึ้นอยู่กับว่า Progress ในขณะนั้นเกี่ยวกับอะไร และจะนำมาคำนวณเพื่อแสดงผลความคืบหน้าของ Process
แสดสถานะของ ProgressBar แบบ Horizontal แสดงสถานะความคืบหน้า และ เปอร์เซ็นต์
XML Syntax
<ProgressBar (Horizontal)
android:id="@+id/progressBar1"
android:style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
การสร้าง ProgressBar แบบ Loading วงกลม
Example 1 การใช้ ProgressBar แบบ Horizontal ง่าย ๆ แสดงสถานะ 0 - 100%
ออกแบบหน้าจอ GraphicalLayout ด้วย Widget ตามรูป
activity_main.xml (XML Layout)
<?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" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:text="Do Work!" />
</LinearLayout>
สร้าง XML Layout ประกอบด้วย button1 มี Text ว่า "Do Work!" โดยวัตถุประสงค์คือ เมื่อกดปุ่ม button1 จะแสดง Popup ของ ProgressBar แว้ลสถานะและเปอร์เซ็นต์ที่ทำงานอยู่ในขณะนั้น
MainActivity.java (Java Code)
package com.myapp;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.app.ProgressDialog;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
Button btnDoWork;
ProgressDialog progressBar;
private int progressBarStatus = 0;
private Handler progressBarHandler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// button1 Do Work
btnDoWork = (Button) findViewById(R.id.button1);
btnDoWork.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { // Start Event onClick
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(true);
progressBar.setMessage("Working... ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
progressBarStatus = 0;
new Thread(new Runnable() {
public void run() {
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = DoWork();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
}
}).start();
} // End Event onClick
});
}
// DoWork & Set Status Progress Bar
public int DoWork() {
// Do some work EG: Save , Download , Insert , ..
// **** Work
// **** Work
// **** Work
// **** Work
progressBarStatus++; // Work process and return status
if( progressBarStatus < 100)
{
return progressBarStatus;
}
// When Finish
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.dismiss();
return 100;
}
}
คำอธิบาย
จาก Loop ที่เป็น while (progressBarStatus < 100) { คือจะทำงานซ้ำ ๆ จน progressBarStatus = 100
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = DoWork();
Thread.sleep(300); // หยุดการทำงานประมาณ 0.3 วินาที
}
จะเห็นว่าใน Loop ของ while จะมีการดึงค่า progressBarStatus มาจาก Method ของ DoWork เพาะฉะนั้นถ้า progressBarStatus = 100 ก็แสดงว่า Loop นี้ทำงานเสร็จสิ้น
อธิบายเกี่ยวกับ Method ของ DoWork()
ใน Method ของ DoWork() นั้จะเป็นตัวสำคัญที่จะเขียนเงื่อนไขในการทำงาน และการแสดงสถานะของ progressBar และการคำนวณความคืบหน้า
public int DoWork() {
// Do some work EG: Save , Download , Insert , ..
// **** Work
// **** Work
// **** Work
// **** Work
progressBarStatus++; // Work process and return status
if( progressBarStatus < 100)
{
return progressBarStatus;
}
// When Finish
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.dismiss();
return 100;
}
ในตัวอย่างนี้จะเห็นว่าเป็นแค่การ Return ค่า progressBarStatus++ คือจะ Return 1...2...3 จนถึง 100 และเมื่อครบ 100 ก็จะทำการหยุดการทำงานของ progressBar ด้วย progressBar.dismiss();
แต่ในหลัการทำงานจริง ๆ แล้ว เช่นถ้าเรามีรายการ Record ที่จะต้อง Insert ข้อมูล 1000 Record เราอาจจะเขียนเงื่อนไขในการคำนวณว่า กี่ทำไปแล้วกี่ Record และจะให้ส่งค่า progressBarStatus ไปเท่าไหร่
และการทำงานจริงไม่จำเป็นจะต้องใช้ Thread.Sleep() แต่อย่างใด เพระเราจะได้ Process จากการทำงานจริงมาแสดงการทำงานในขณะนั้นจริง ๆ
public int DoWork() {
int job = 1000;
int process = job / 100;
for(i=1;i<=job;i++)
{
Call insert data method();
if(i % process == 0)
{
progressBarStatus = progressBarStatus + 1; // Work process and return status
}
}
if( progressBarStatus < 100)
{
return progressBarStatus;
}
// When Finish
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.dismiss();
return 100;
}
จากตัวอย่างเมื่อมีการเรียก Call insert data method(); ครบ 10 Record ก็จะส่ง Status ไป +1 กลับไป ซึ่งจะทำงานจนครบ 1000 Record และ Status จะเท่ากับ 100 พอดี
Screenshot
แสดงการทำงาน ProgressBar แบบ (Horizontal)
เพิ่มเติม
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
STYLE_SPINNER สำหรับ ProgressBar แบบวงกลม โหลดดิ้ง
Example 2 ตัวอย่างการใช้ Progress เพื่อดาวน์โโหลดไฟล์จาก Server และเก็บลงใน SD Card
Android ทำการ Copy ไฟล์ไปยัง SD Card ของ Emulator การเรียกใช้งานไฟล์บน SD Card
สำหรับพื้นฐานของ SD Card สามารถอ่านได้จากบทความนี้
ออกแบบหน้าจอ GraphicalLayout ด้วย Widget ตามรูป
เพิ่มคำสั่งนี้ลงในไฟล์ AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
AndroidManifest.xml
เพิ่มในตำแหน่งดังรูป โดยเพิ่มทั้ง 2 บรรทัด อตัวแรกเป็นการกำหนดสิทธิ์ให้สามารถใช้ Internet ตัวที่สองสิทธิ์ในการเขียนไฟล์ลงใน SD Card
activity_main.xml (XML Layout)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Start Download" />
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/button1"
android:layout_alignParentLeft="true"
android:layout_marginBottom="61dp"
android:ems="10"
android:textSize="12dp"
android:gravity="center" />
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="37dp"
android:gravity="center"
android:text="Enter URL for Download" />
</RelativeLayout>
ใน XML layout ประกอบด้วย ช่องสำหรับกรอก URL และปุ่ม Button สำหรับ Download
MainActivity.java (Java Code)
package com.myapp;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private Button startBtn;
private ProgressDialog mProgressDialog;
private String URLDownload;
private EditText txtURL;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// button1
startBtn = (Button)findViewById(R.id.button1);
startBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
startDownload();
}
});
}
private void startDownload() {
// editText1
txtURL = (EditText)findViewById(R.id.editText1);
URLDownload = txtURL.getText().toString();
new DownloadFileAsync().execute(URLDownload);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
// Get File Name from URL
String fileName = URLDownload.substring( URLDownload.lastIndexOf('/')+1, URLDownload.length() );
OutputStream output = new FileOutputStream("/sdcard/MyData/"+fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
}
จาก Code Java จะเห็นว่ามีการ Save ลงใน FileOutputStream("/sdcard/MyData/"+fileName); ซึ่งเป็นโฟเดอร์ที่อยู่ใน SD Card
เมื่อไปดูใน /sdcard/ จะมีตำแหน่ง Path เป็น /mnt/sdcard/ และถถ้ากำหนดเป็น /sdcard/MyData/ ก็จะได้ Path จริง ๆ เป็น
Code
/mnt/sdcard/MyData
หรือจะเรียกใช้
Code
FileOutputStream("/mnt/sdcard/MyData/"+fileName);
ซึ่งมีค่าเหมือนกัน และการเขียนไฟล์หรือ Copy ไฟล์ลงในโฟเดอร์จะต้องดูในรื่องสิทธิ์ของการเขียนไฟล์และโฟเดอร์ด้วย
Screenshot
เมื่อทดสอบการทำงานก็จะแสดงช่อง TextBox สำหรับกรอก URL ของไฟล์
กรอก URL ของไฟล์ที่ต้องการดาวน์โหลด
กำลังดาวน์โหลด และแสดง ProgressBar สถานะและเปอร์เซ็นต์ จนทำงานเสร็จสิ้น
หลังจากทำงานเสร็จสิ้น เมื่อตรวจสอบที่ /mnt/sdcard/MyData/ ก็จะพบกับไฟล์ที่เราได้ดาวน์โหลดมา
Property & Method (Others Related) |
|
ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท
|
|
|
By : |
ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ) |
|
Score Rating : |
|
|
|
Create/Update Date : |
2012-07-01 15:57:09 /
2012-08-02 07:29:57 |
|
Download : |
No files |
|
Sponsored Links / Related |
|
|
|
|
|
|
|