如何在Android中显示带有百分比的ProgressBar示例

9

我有一个任务,需要在用户想要进行预测时添加一个带有百分比值的 ProgressBar 来显示进度。由于使用了过时的 ProgressDialog ,因此我没有使用它。这里,百分比值取决于从开始请求到完成请求所需的时间长度。我正在使用 Volley 从服务器获取数据。

以下是我想要实现的样例图片:

ProgressBar Percentage Value

我已经像这样做了:

我在警告对话框中实现了一个水平进度条(我使用这种方式是因为进度对话框已过时)。我想设置进度条的进度如下图所示。

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view =  inflater.inflate(R.layout.fragment_result_prediction, container, false);
    predictProgress = (ProgressBar) view.findViewById(R.id.progressbarPredict);
    AlertDialog.Builder(view.getContext());
    builder.setCancelable(false); // if you want user to wait for some process to finish,
    View v = inflater.inflate(R.layout.layout_loading_dialog, null);
    builder.setView(v);
    final AlertDialog dialog = builder.create();
    submitPredictPlant.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                dialog.show();
                predictProgress.setProgress(25);
                predictProgress.setProgress(50);
                predictProgress.setProgress(75);
                predictProgress.setProgress(100);
                dialog.dismiss();

我希望在进度条达到100时关闭对话框。但是这会导致以下错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setProgress(int)' on a null object reference

我已经从builder.setview中使用的layout_loading_dialog引用了进度条。

这是layout_loading_dialog.xml文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_weight="4"
    android:gravity="center"
    android:text="Please wait! This may take a moment." />

<ProgressBar
    android:layout_width="match_parent"
    android:id="@+id/progressbarPredict"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    style="?android:attr/progressBarStyleHorizontal"/>


你好,欢迎来到SO。请阅读[提问]和[mcve]。 - Sfili_81
不要使用已被弃用的progressDialog,你可以使用进度条。 - Abdul
你能再检查一下我的问题吗?我已经添加了一些代码,谢谢。 - Vapor
是的,创建一个带有进度条的。 - Abdul
现在的问题是,当我想要在layout_loading_progress.xml上设置进度条时,我会得到空对象引用。 - Vapor
请检查以下代码,当进度等于100时,它将自动关闭。 - Abdul
2个回答

9
以下是创建带有百分比的进度对话框的代码,就像图片中显示的一样。
int status = 0;
Handler handler = new Handler();

public void showDialog(Activity activity, String msg) {
    final Dialog dialog = new Dialog(activity);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setCancelable(false);
    dialog.setContentView(R.layout.dialog);

    final ProgressBar text = (ProgressBar) dialog.findViewById(R.id.progress_horizontal);
    final TextView text2 = dialog.findViewById(R.id.value123);


    new Thread(new Runnable() {
        @Override
        public void run() {
            while (status < 100) {

                status += 1;

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

                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        text.setProgress(status);
                        text2.setText(String.valueOf(status));

                        if (status == 100) {
                            dialog.dismiss();
                        }
                    }
                });
            }
        }
    }).start();


    dialog.show();

    Window window = dialog.getWindow();
    window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
}

布局文件:对话框

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">

<ProgressBar
    android:id="@+id/progress_horizontal"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp" />

<RelativeLayout
    android:layout_width="wrap_content"
    android:paddingLeft="20dp"
    android:layout_margin="16dp"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/value123"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
      />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/value123"
        android:text="%" />
</RelativeLayout>

结果:

这里输入图片描述 使用Asyntask:

int status = 0;
Handler handler = new Handler();
Dialog dialog;
ProgressBar text;
TextView text2;

public void showDialog(Activity activity, String msg) {
    dialog = new Dialog(activity);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setCancelable(false);
    dialog.setContentView(R.layout.dialog);

    text = (ProgressBar) dialog.findViewById(R.id.progress_horizontal);
    text2 = dialog.findViewById(R.id.value123);


    dialog.show();

    Window window = dialog.getWindow();
    window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (status < 100) {

                status += 1;

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

                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        text.setProgress(status);
                        text2.setText(String.valueOf(status));

                        if (status == 100) {
                            status = 0;
                        }
                    }
                });
            }
        }
    }).start();

}


private class AsyncTaskRunner extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {


        // it will fill the progress bar to 100
        // and will refill again and again



        /*
         *
         * Make your api call here
         * MAke request to API and return data when response comes
         *
         *
         * */

        /*
        * 
        * I have just add sleep to thead for example purposes
        * 
        * */
        try {
            Thread.sleep(30 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return resp;
    }


    @Override
    protected void onPostExecute(String result) {


        /*
         *
         *
         * Do your processing there on the api result
         *
         *
         * */
        dialog.dismiss();
    }


    @Override
    protected void onPreExecute() {
        showDialog(MainActivity.this,"");

    }


    @Override
    protected void onProgressUpdate(String... text) {

    }
}

开始使用Asyntask:

    new AsyncTaskRunner().execute("fs");

我不确定这是否是最佳方法。


但是进度对话框已经被弃用了,使用它还可以吗? - Vapor
使用 AsyncTask,在 onPreExecute 中显示对话框,在 doInBackground 中进行 Volley 调用,在 postExecute 中关闭对话框。 - Abdul
所以在onPreExecute中,我声明了你提供的除线程和setProgress(0)之外的所有代码,然后在doInBackground中调用一个函数来请求服务器,在postExecute中将进度设置为100,然后关闭对话框并意图到一个新页面?我的理解正确吗? - Vapor
在你的第一段代码中,更新进度条是否安全在线程内部进行?难道不应该在UI线程上执行吗? - Sujit
我们有一个处理程序,它正在与用户界面通信。 - Abdul
显示剩余4条评论

1

如果有人正在寻找带有百分比的圆形进度条,这里是 Kotlin 版本。

class PercentageProgressBar : ProgressBar {

    private lateinit var textPaint: Paint
    private lateinit var circlePaint: Paint
    private var currentProgress = 0

    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init()
    }

    private fun init() {
        setWillNotDraw(false)

        circlePaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
        val whileColor = ContextCompat.getColor(context, android.R.color.white)
        circlePaint.color = whileColor

        textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
        val blackColor = ContextCompat.getColor(context, android.R.color.black)
        textPaint.color = blackColor
        textPaint.textSize = 20F
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val w = MeasureSpec.getSize(widthMeasureSpec)
        val h = MeasureSpec.getSize(heightMeasureSpec)
        val size = w.coerceAtMost(h)
        setMeasuredDimension(size, size)
    }

    private val r: Rect = Rect()

    override fun onDraw(canvas: Canvas) {

        val circleX = (width / 2).toFloat()
        val circleY = (height / 2).toFloat()
        val radius = (width / 2.5).toFloat()
        canvas.drawCircle(circleX, circleY, radius, circlePaint);

        // https://dev59.com/OWgu5IYBdhLWcg3wuJWF#32081250
        val textToPrint = "$currentProgress %"
        canvas.getClipBounds(r)
        val cHeight: Int = r.height()
        val cWidth: Int = r.width()
        textPaint.textAlign = Paint.Align.LEFT
        textPaint.getTextBounds(textToPrint, 0, textToPrint.length, r)
        val x: Float = cWidth / 2f - r.width() / 2f - r.left
        val y: Float = cHeight / 2f + r.height() / 2f - r.bottom
        canvas.drawText(textToPrint, x, y, textPaint)
        super.onDraw(canvas)
    }

    override fun setProgress(progress: Int) {
        super.setProgress(progress)
        
        // Hide when progress is 100
        if (progress == 100) {
            visibility = View.GONE
            return
        }
        currentProgress = progress
        invalidate()
    }
}

请问如何使用它? - Sos.
@زياد 使用它就像使用默认的“ProgressBar”一样。 - OhhhThatVarun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接