最近要做的項目都涉及到了服務器請求和藍牙連接等耗時操作,在處理這些耗時操作時需要考慮到用戶體驗就必須弄個等待對話框。於是便打算自定義一下等待框的樣式,使其達到其需求,同時也將其封裝起來,到時要用的時候就可以方便直接用了。
效果圖:
1. 先定義一個會旋轉的shape,用做無進度的圓形progressBar。
shape_rotate_progressbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360">
<shape
android:innerRadiusRatio="3"
android:thicknessRatio="9"
android:useLevel="false"
android:shape="ring">
<gradient
android:centerColor="#ffffff"
android:centerY="0.50"
android:startColor="#666666"
android:endColor="#ffdd11"
android:type="sweep"
android:useLevel="false"/>
</shape>
</rotate>
2. 定義dialog佈局里根容器的背景色和圓角效果。
shape_loading_dialog_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="8dp"/>
<solid android:color="#88ffffff"/>
</shape>
3. 定義dialog佈局。
dialog_loading.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="160dp"
android:layout_height="160dp"
android:background="@drawable/<span style="color:#ff0000;">shape_loading_dialog_bg</span>"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/dialog_progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingBottom="15dp"
android:layout_centerInParent="true"
android:indeterminateDrawable="@drawable/<span style="color:#ff0000;">shape_rotate_progressbar</span>"/>
<TextView
android:id="@+id/loading_dialog_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/dialog_progressBar"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textSize="15sp"
android:textColor="#FFDD11"/>
</RelativeLayout>
在此佈局文件裏用上1. 2 步創建的shape
4. 在styles.xml裏聲明自定義樣式dialog風格。
styles.xml:
<style name="loading_dialog_style" parent="android:Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
5. 創建dialog的子類,並加載dialog佈局。
LoadingDialog.java:
public class LoadingDialog extends Dialog {
private String message;
public LoadingDialog(Context context, String message) {
// TODO Auto-generated constructor stub
super(context, R.style.loading_dialog_style);
this.message=message;
}
public LoadingDialog(Context context) {
this(context, "");
// TODO Auto-generated constructor stub
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_loading);
//可以選擇性添加等待對話框的內容文本
if(message!=null && !message.equals("")){
((TextView)findViewById(R.id.loading_dialog_tv)).setText(message);
}else{
((TextView)findViewById(R.id.loading_dialog_tv)).setVisibility(View.GONE);
}
}
}
6. 直接在代碼裏使用。
public class MainActivity extends Activity {
private Button btnShowDialog;
private LoadingDialog dialog;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new Handler();
btnShowDialog=(Button)findViewById(R.id.btn_show_dialog);
btnShowDialog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//顯示自定義樣式的dialog
dialog.show();
//dialog顯示後就可以進行一些耗時操作,比如網絡請求,數據庫處理等
//如果10秒後加載等待還沒結束(即耗時操作還沒完成),則主動取消耗時操作並使dialog消失
handler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if(dialog.isShowing()){
dialog.cancel();
}
}
}, 10000);
}
});
//使用帶文字的構造體創建dialog
dialog=new LoadingDialog(this, null);
//設置不能按屏幕或物理返回鍵退出
dialog.setCancelable(false);
//設置
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
// TODO Auto-generated method stub
//執行取消操作,可以中斷耗時操作
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//handler依賴於activity,結束後要習慣把handler的任務取消掉,避免activity回收不了而內存泄露
if(handler!=null){
handler.removeCallbacksAndMessages(null);
}
}
}
代碼除了MainActivity的layout外,其他都在上面了。
代碼下載:github