1. 程式人生 > >【Android】一、Progress進度條實現的三種方式:主執行緒實現,Service載入,動態建立

【Android】一、Progress進度條實現的三種方式:主執行緒實現,Service載入,動態建立

前言

更新版本,上傳資料到服務端,都是需要進度顯示的,Android進度顯示兩種方式 ProgressDialog 和 ProgressBar

新版本中ProgressDialog不被推薦使用,所以專案採用ProgressBar

分為三種實現方式:

1、MainActivity直接載入,呼叫xml資源顯示

2、Service載入,還是呼叫MainActivity的bar資源顯示,

3、動態載入

如果需要在非主執行緒顯示,可以採用Handler進行資料轉發到主執行緒去顯示

示例程式碼如下:

public class MainActivity extends AppCompatActivity {
    private ProgressBar mProgress;
    private int mProgressStatus = 0;
    public static ProgressBar progressBar;
    private static int PROGRESS = 0;
    private Intent intent;
    private ProgressBar pb = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mProgress = (ProgressBar) findViewById(R.id.progress_bar);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
        intent = new Intent(this, MyServices.class);
    }    

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mProgress.setProgress(mProgressStatus);
        }
    };


    /**
     * TODO: 方式一:顯示預設UI上面的進度條
     */
    public void useProgressByMainThread(View view) {
        Toast.makeText(getApplicationContext(), "useProgressByMainThread", Toast.LENGTH_LONG).show();
        // 把進度條復原
        mProgressStatus = 0;
        new Thread(new Runnable() {
            public void run() {
                mHandler.sendEmptyMessage(0);
            }
        }).start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(new Runnable() {
            public void run() {
                String tag = MainActivity.class.getSimpleName();
                while (mProgressStatus < 100) {
                    mProgressStatus = doWork();
                    mHandler.sendEmptyMessage(0);
                    Log.d(tag, (System.currentTimeMillis()) / 1000 + "" + mProgressStatus);
                }
            }
        }).start();
    }

    public int doWork() {
        try {
            PROGRESS += 1;
            Thread.currentThread();
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return PROGRESS;
    }


    /**
     * TODO: 方式二:在Service控制進度條,還是回到MainActivity進行顯示
     */
    public void useProgressByService(View view) {
        Toast.makeText(getApplicationContext(), "useProgressByService", Toast.LENGTH_LONG).show();

        // 把進度條復原
        mProgressStatus = 0;
        new Thread(new Runnable() {
            public void run() {
                mHandler.sendEmptyMessage(0); // 用執行緒才能重新整理進度條,否則無效
            }
        }).start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 開啟服務進行進度條控制
        startService(intent);
    }

    /**
     * TODO: 方式三:動態建立進度條
     * https://blog.csdn.net/chdjj/article/details/19825145
     */
    public void useProgressByDynamic(View view) {
        pb = this.createProgressBar(this);
        pb.setVisibility(View.VISIBLE);
    }

    public ProgressBar createProgressBar(Activity a) {
        // 1.找到activity根部的ViewGroup,型別都為FrameLayout。
        FrameLayout rootContainer = (FrameLayout) a.findViewById(android.R.id.content);//固定寫法,返回根檢視

        // 2.初始化控制元件顯示的位置
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        lp.gravity = Gravity.CENTER;

        // 3.設定控制元件顯示位置
        ProgressBar pb = new ProgressBar(a);
        pb.setLayoutParams(lp);
        pb.setVisibility(View.GONE);//預設不顯示

        // 4.將控制元件加到根節點下
        rootContainer.addView(pb);
        return pb;
    }
}
public class MyServices extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("test","onCreate");
    }

    @Override
    public int onStartCommand(Intent intent,int flags, int startId) {
        new MyThread(intent,startId).start();
        Log.i("test","onStartCommand");
        return Service.START_STICKY;
    }

    class MyThread extends Thread{
        private int startId;
        private  Intent intent;

        public MyThread(Intent intent,int startId){
            this.startId=startId;
            this.intent=intent;
        }


        Handler handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                int i=msg.what;
                MainActivity.progressBar.setProgress(i);
            }
        };

        @Override
        public void run() {
            for (int i =1; i <=100 ; i++) {
                handler.sendEmptyMessage(i);
                SystemClock.sleep(200);
                Log.i("test","   "+i);
            }
            //服務執行完畢後自動呼叫onDestroy方法
            stopSelf(startId);
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("test","onDestroy");
    }
}
xml配置
   <service android:name =".MyServices" ></service>
layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ProgressBar
        android:id="@+id/progress_bar"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="70dp"
        android:layout_marginRight="70dp" />

    <Button
        android:id="@+id/btn0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="useProgressByMainThread"
        android:text="方式一,主執行緒用進度條"
        tools:ignore="OnClick" />

    <Button
        android:id="@+id/btn00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="useProgressByService"
        android:text="方式二,Service啟用進度條"
        tools:ignore="OnClick" />

    <Button
        android:id="@+id/btn000"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="useProgressByDynamic"
        android:text="方式三,動態建立進度條"
        tools:ignore="OnClick" />
</LinearLayout>

參考: