1. 程式人生 > >Android 自定義Dialog,文字動態載入效果。

Android 自定義Dialog,文字動態載入效果。

之前在技術問答上面看到一個提問 “載入中…” 後面三個點是動態的,這麼一個效果實現。想來想去,好像沒想到好的處理方式。
嘗試了一下,以一個最笨的方式實現了。先來看一下效果 :

我是通過自定義一個Dialog,載入中的效果,是在Dialog內部實現的,進度還是從Activity裡面控制的。
下面是Dialog實現類:

public class CustomDialog extends AlertDialog {
    public CustomDialog(Context context) {
        super(context);
    }

    private
TextView tv_loading; private ProgressBar progressBar; private Timer timer; private int count = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_progress); tv_loading = (TextView) findViewById(R.id.tv_loading); progressBar = (ProgressBar) findViewById(R.id.pb); // 設定Dialog顯示的寬度,
Display d = getWindow().getWindowManager().getDefaultDisplay(); WindowManager.LayoutParams lp = getWindow().getAttributes(); //這裡設定為螢幕寬度的百分之八十 lp.width = (int) (d.getWidth() * 0.8); getWindow().setAttributes(lp); timer = new Timer(); timer.schedule(new
TimerTask() { @Override public void run() { handler.sendEmptyMessage(0); } }, 300, 300); setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { if (timer != null) { timer.cancel(); } } }); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { count++; if (count > 3) { count = 1; } switch (count) { case 1: tv_loading.setText("載入中."); break; case 2: tv_loading.setText("載入中.."); break; case 3: tv_loading.setText("載入中..."); break; } } }; public void setProgress(int progress) { progressBar.setProgress(progress); if (progress == 100) { this.dismiss(); } } }

佈局檔案就一個TextView,一個ProgressBar,
dialog_progress.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:background="@drawable/shape_dialog_bg"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:text="載入中..."
        android:textSize="16sp" />

    <ProgressBar
        android:id="@+id/pb"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:max="100"
        android:progressDrawable="@drawable/layer_list_progress_drawable" />


</LinearLayout>

因為沒想到其他的思路,所以,只能通過Timer 來計時改變TextView的顯示。。(這裡也希望各位大神能指點一下,目前確實想不到其他思路)
ProgressBar的樣式,上一篇Android 自定義水平進度條的圓角進度裡面有詳細介紹,這裡就不重複了。
Dialog就是這樣。然後就是呼叫了:
MainActivity.class

public class MainActivity extends FragmentActivity {


    private CustomDialog customDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        customDialog = new CustomDialog(this);

    }

    private int count = 0;

    public void tvClick(View view) {
        customDialog.show();
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                count += 10;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (customDialog != null && customDialog.isShowing()) {
                            customDialog.setProgress(count);
                        }
                    }
                });
                if (count >= 100) {
                    timer.cancel();
                }
            }
        }, 0, 500);
        customDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if (timer != null) timer.cancel();
                count = 0;
            }
        });

    }

}

這裡也是用的Timer來模擬載入進度,(寫的過程中感覺Timer的定時操作比其他兩種方式用起來方便多了)。
點選事件我是通過在xml裡面直接呼叫的。

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:clickable="true"
        android:onClick="tvClick"
        android:padding="10dp"
        android:text="點選彈框" />

clickable屬性不加上的話,有些手機系統預設是沒法呼叫的(之前遇到過小米的,不加這個屬性,不觸發click事件)
另外,這種click事件的寫法在Fragment是不可用的,只能通過setOnClickListener來觸發。

更新一種實現方式:
感謝 IT-hero ,又 get 一個 屬性動畫的用法。
下面是 自定義Dialog 裡的一些調整 :

private String[] scoreText = {".  ", ".. ", "..."};
ValueAnimator valueAnimator;

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.dialog_progress);
     tv_loading = (TextView) findViewById(R.id.tv_loading);
     progressBar = (ProgressBar) findViewById(R.id.pb);

     // 設定Dialog顯示的寬度,
     Display d = getWindow().getWindowManager().getDefaultDisplay();
     WindowManager.LayoutParams lp = getWindow().getAttributes();
     //這裡設定為螢幕寬度的百分之八十
     lp.width = (int) (d.getWidth() * 0.8);
     getWindow().setAttributes(lp);

     if (valueAnimator == null) {
         valueAnimator = ValueAnimator.ofInt(0, 3).setDuration(1000);
         valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
         valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 int i = (int) animation.getAnimatedValue();
                 tv_loading.setText("載入中" + scoreText[i % scoreText.length]);
             }
         });
     }
     valueAnimator.start();
}
//程式碼省略...

因為沒找到 CSDN編輯上傳資源 的方式,所以這裡 Demo 裡面就沒有新增這個屬性動畫的程式碼,有需要的朋友可以直接從這裡copy。

還望各路朋友多多指點。

程式碼不多,作為隨手筆記。