说来惭愧,由于刚学Android不久就开始做项目,虽然刚开始做的时候只用了一个月就写好了基本功能,但由于考虑不周全,有些如检测版本自动更新、查看缩略图等应有功能没有想到,导致一个差不多半年前接下的项目,到现在还在修修补补。不过开发的过程中需求也在不断变化,算是初次经历到了所谓“增量开发”的工作。
回到正题
Android给我们提供了许多控件,但这些原生控件往往不能满足我们的需求,因此这就需要进行自定义。
先看一个普通的Dialog
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("标题")
.setMessage("内容")
.setPositiveButton("确定",nul
.setNegativeButton("取消",null)
.create();
dialog.show();
之前我写过说明如何自定义Dialog中控件属性的文章
利用反射机制修改Dialog的各文字组件的颜色、字体大小等属性
可供有需要的朋友参考
在Dialog中设置自定义View
- 设置自定义布局文件。
progress_layout.xml:借鉴了Android自带的ProgressDialog的布局文件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="1dp"
android:layout_marginEnd="25dp"
android:layout_marginStart="25dp"
android:layout_marginTop="12dp"/>
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/progress_bar"
android:layout_marginEnd="25dp"
android:layout_marginStart="25dp"
android:paddingBottom="12dp"/>
<TextView
android:id="@+id/progress_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/progress_bar"
android:layout_marginEnd="25dp"
android:layout_marginStart="25dp"
android:paddingBottom="12dp"/>
</RelativeLayout>
- 使用AlertDialog.Builder中的setView()方法
其中initFormats()、updateProgressView()均借鉴了ProgressDialog源码中的方法。
//设置进度条说明文字格式
private void initFormats() {
mProgressNumberFormat = "%1d/%2d";
mProgressPercentFormat = NumberFormat.getPercentInstance();
mProgressPercentFormat.setMaximumFractionDigits(0);
}
@NonNull
public View initProgressView() {
initFormats();
LayoutInflater inflater = LayoutInflater.from(DownloadService.this.context);
final View progressView = inflater.inflate(R.layout.progress_layout, null);
progressBar = progressView.findViewById(R.id.progress_bar);
progress_number = progressView.findViewById(R.id.progress_number);
progress_percent = progressView.findViewById(R.id.progress_percent);
final String format = mProgressNumberFormat;
progress_number.setText(String.format(format, 0, 100));
SpannableString tmp = new SpannableString(mProgressPercentFormat.format(0));
tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
progress_percent.setText(tmp);
progressView.setVisibility(View.INVISIBLE);//此处先隐藏ProgressBar,点击确定后才显示。
return progressView;
}
@SuppressLint("HandlerLeak")
public void showProgressDialog() {
//加载自定义ProgressBar
final View progressView = initProgressView();
name = SPUtils.getPrefString("new_name", null);
updateContent = SPUtils.getPrefString("updateContent", null);
/*自定义Title内容
TextView title = new TextView(所在Context);
title.setText(标题内容);
title.setTextSize(20);
title.setGravity(Gravity.CENTER);
title.setTextColor(getColor(R.color.colorAccent));
*/
AlertDialog.Builder builder = new AlertDialog.Builder(所在Context);
builder.setTitle(标题内容);
//builder.setCustomTitle(title);设置自定义标题布局
builder.setIcon(标题图片);
builder.setMessage(详细内容);
builder.setView(progressView);//此处设置自定义ProgressBar
builder.setPositiveButton("确定", null);
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelDownload();
}
});
progressDialog = builder.create();
progressDialog.show();
//此处利用反射自定义Dialog的标题、内容的颜色、文字大小等属性
try {
Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
mAlert.setAccessible(true);
Object mAlertController = mAlert.get(progressDialog);
Field mTitle = mAlertController.getClass().getDeclaredField("mTitleView");
mTitle.setAccessible(true);
TextView mTitleView = (TextView) mTitle.get(mAlertController);
mTitleView.setTextColor(getColor(R.color.colorAccent));
Field mMessage =mAlertController.getClass().getDeclaredField("mMessageView");
mMessage.setAccessible(true);
TextView mMessageView = (TextView) mMessage.get(mAlertController);
mMessageView.setGravity(Gravity.CENTER);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
progressDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(想要的颜色);
progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置想要的操作
progressView.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
int progress = 0;
@Override
public void run() {
while (progress <= 100) {
progressBar.setProgress(progress);
handler.sendEmptyMessage(0);
//if (progress == 100) {
//progressDialog.dismiss();
//}
try {
Thread.sleep(35);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress++;
}
}
}).start();
});
updateProgressView(progressView);
}
/**
*更新进度条下的进度文字
*/
@SuppressLint("HandlerLeak")
private void updateProgressView(View view) {
final String format = mProgressNumberFormat;
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
/* Update the number and percent */
int progress = progressBar.getProgress();
int max = progressBar.getMax();
if (mProgressNumberFormat != null) {
progress_number.setText(String.format(format, progress, max));
} else {
progress_number.setText("");
}
if (mProgressPercentFormat != null) {
double percent = (double) progress / (double) max; SpannableString tmp1=newSpannableString(mProgressPercentFormat.format(percent));
tmp1.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
0, tmp1.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
progress_percent.setText(tmp1);
} else {
progress_percent.setText("");
}
if (progress == progressBar.getMax()) {
//progressDialog.dismiss();
}
}
};
}
顺带提一句,Title也可以自定义,同样只需调用setCustomTitle()方法及自定义布局文件。
至此,大功告成,让我们看一下最终效果:
Github地址:DIYProgressDialog