Android--实现带ProgressBar的自定义Dialog

说来惭愧,由于刚学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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值