2014/12/06

[Android] 利用AsyncTask和ProgressDialog來做Activity之間切換的效果

通常在APP在下載資料或者切換到另外一個畫面時,常常會需要等到資料載入完成後,才能夠切換畫面。這時候可以做一個ProgressDialog的效果,讓使用者知道目前的下載進度。

所以利用AsyncTask來控制ProgressDialog,以及切換到下一個Activity,就可以完成這樣一個切換Activity之間的效果。



一、首先AsyncTask的主要有四大部分

  1. doInBackground:這裡要放需要載入或下載的部分,完成一個後呼叫publishProgress來執行onProgressUpdate更新目前的狀況
  2. onPreExecute:產生一個ProgressDialog
  3. onProgressUpdate:根據doInBackground的結果來更新ProgressDialog
  4. onPostExecute:載入完成之後,切換到第二個Activity

二、ProgressDialog的設定

  1. setTitle:設定標題
  2. setMessage:設定提示訊息
  3. setProgressStyle:設定要使用水平進度條(STYLE_HORIZONTAL)或圓形旋轉(STYLE_SPINNER)
  4. setProgress:設定目前的Porgress位置,初始值為0
  5. setMax:Porgress最大值
  6. incrementProgressBy:每次增加多少

三、切換Activity
利用Intent來切換Activity,值得注意的是在AndroidManifest.xml中要宣告新的Activity,否則會無法成功切換到下一個Activity
<activity
    android:name="com.example.asynctask.SecondAcitvity"
    android:label="@string/app_name" >
</activity>


四、程式碼

  1. MainActivity.java:主Activity
  2. AlertDialog.java:用AsyncTask父類別來控制產生的ProgressDialog效果
  3. SecondAcitvity.java:第二個Activity

MainActivity.java
package com.example.asynctask;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
 
 // String for LogCat documentation
 private final static String TAG = "AsyncTask-MainAcitvity";
 private Button btnStart;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Log.i(TAG,"Enter onCreate().");
  
  btnStart = (Button) findViewById(R.id.buttonStart);
  btnStart.setOnClickListener(btnListener);
  
 }
 
 private Button.OnClickListener btnListener = new OnClickListener() {
  
  @Override
  public void onClick(View v) {
   // TODO Auto-generated method stub
   Log.i(TAG, "On Start Button Click!");
   new AlertDialog(MainActivity.this).execute();
  }
 };
 
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // Handle action bar item clicks here. The action bar will
  // automatically handle clicks on the Home/Up button, so long
  // as you specify a parent activity in AndroidManifest.xml.
  int id = item.getItemId();
  if (id == R.id.action_settings) {
   return true;
  }
  return super.onOptionsItemSelected(item);
 }
}

activity_main.xml
<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"
    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="com.example.asynctask.MainActivity" >

    <TextView
        android:id="@+id/textViewMain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/buttonStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/textViewMain"
        android:layout_below="@+id/textViewMain"
        android:layout_marginTop="22dp"
        android:text="Start" />

</RelativeLayout>

AlertDialog.java
package com.example.asynctask;

import java.net.URL;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;

public class AlertDialog extends AsyncTask {
 
 // String for LogCat documentation
 private final static String TAG = "AsyncTask-AlertDialog";
 private Activity mParentActivity;
 
 private final CharSequence DialogTitle = "Loading";
 private final CharSequence DialogMessage = "Wait to load data...";
 
 // ProgressDialog
 private ProgressDialog barProgressDialog;
 private int fileNumber = 10;
 private int diff = 1;
 private String doInReturn = "ok";
  
 public AlertDialog(Activity parentActivity) {
  // TODO Auto-generated constructor stub
  super();
  mParentActivity = parentActivity;
 }
 
 @Override
 protected String doInBackground(URL... urls) {
  // TODO Auto-generated method stub
  int progress = 0;
  while(progress<=fileNumber) {
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   publishProgress(Integer.valueOf(progress));
   progress++;
  }
  return doInReturn;
 }

 @Override
 protected void onPreExecute() {
  // TODO Auto-generated method stub
  Log.i(TAG, "AlertDialog onPreExecute().");
  barProgressDialog = new ProgressDialog(mParentActivity);
  
  barProgressDialog.setTitle(DialogTitle);
  barProgressDialog.setMessage(DialogMessage);
  barProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  barProgressDialog.setProgress(0);
  barProgressDialog.setMax(fileNumber);
  barProgressDialog.show();
  super.onPreExecute();
 }
 
 @Override
 protected void onProgressUpdate(Integer... progress) {
  // TODO Auto-generated method stub
  Log.i(TAG, "AlertDialog onProgressUpdate() "+ progress.toString());
  barProgressDialog.incrementProgressBy(diff);
  super.onProgressUpdate(progress);
 }
 
 @Override
 protected void onPostExecute(String result) {
  // TODO Auto-generated method stub
  Log.i(TAG, "DownloaderTask onPostExecute().");
  if(result.equals(doInReturn)) {
   barProgressDialog.dismiss();
   Intent intent = new Intent();
   intent.setClass(mParentActivity, SecondAcitvity.class);
   // Launch the Activity using the intent
   mParentActivity.startActivity(intent);
  }
  super.onPostExecute(result);
 }
}


SecondAcitvity.java
package com.example.asynctask;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SecondAcitvity extends Activity {
 
 // String for LogCat documentation
 private final static String TAG = "AsyncTask-SecondAcitvity";
 
 private Button btnFinish;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.acitvity_second);
  Log.i(TAG,"Enter onCreate().");
  
  btnFinish = (Button) findViewById(R.id.buttonFinish);
  btnFinish.setOnClickListener(btnLinster);
 }
 
 private Button.OnClickListener btnLinster = new OnClickListener() {
  
  @Override
  public void onClick(View v) {
   // TODO Auto-generated method stub
   finish();
  }
 };
}

acitvity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewSecond"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Second Acitvity" />

    <Button
        android:id="@+id/buttonFinish"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Finish" />

</LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.asynctask"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.asynctask.SecondAcitvity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>

GitHub AsyncTask

五、執行結果




沒有留言:

張貼留言