Android 圆形进度条(用于倒数计时器)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20010997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:08:35  来源:igfitidea点击:

Circular Progress Bar ( for a countdown timer )

androidxmlandroid-animationcountdowntimer

提问by David Baez

Ok so I have a countdown timer of 15 seconds that works perfectly fine and I'd like to make a custom circular progress bar for that timer.

好的,所以我有一个 15 秒的倒数计时器,它工作得非常好,我想为该计时器制作一个自定义的圆形进度条。

I want to create a full circle that gets "slices of the pie (circle)" taken out as the timer goes down until there is no longer a circle.

我想创建一个完整的圆圈,当计时器下降直到不再有圆圈时,它会取出“馅饼(圆圈)的切片”。

I'd prefer to make the shapes myself than use pre-made images because I'd like the quality to be good on any phone. How would I go about this? Thanks!

我更喜欢自己制作形状而不是使用预先制作的图像,因为我希望质量在任何手机上都很好。我该怎么办?谢谢!

回答by Grancein

I found this example very good: http://mrigaen.blogspot.it/2013/12/create-circular-progress-bar-in-android.html

我发现这个例子非常好:http: //mrigaen.blogspot.it/2013/12/create-circular-progress-bar-in-android.html

So I created my progress bar in this way

所以我以这种方式创建了我的进度条

<ProgressBar
    android:id="@+id/barTimer"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true"
    android:progressDrawable="@drawable/circular_progress_bar" />

Then I made a function for the countdown where:

然后我做了一个倒计时函数,其中:

private void startTimer(final int minuti) {
    countDownTimer = new CountDownTimer(60 * minuti * 1000, 500) {
        // 500 means, onTick function will be called at every 500 milliseconds

        @Override
        public void onTick(long leftTimeInMilliseconds) {
            long seconds = leftTimeInMilliseconds / 1000;
            int barVal= (barMax) - ((int)(seconds/60*100)+(int)(seconds%60));
            barTimer.setProgress(barVal);
            textTimer.setText(String.format("%02d", seconds/60) + ":" + String.format("%02d", seconds%60));
            // format the textview to show the easily readable format

        }
        @Override
        public void onFinish() {
            if(textTimer.getText().equals("00:00")){
                textTimer.setText("STOP");          
            }
            else{
                textTimer.setText("2:00");
            }
        }
    }.start();

}

UPDATE

更新

private void startTimer(final int minuti) {
    countDownTimer = new CountDownTimer(60 * minuti * 1000, 500) {
        // 500 means, onTick function will be called at every 500 milliseconds

        @Override
        public void onTick(long leftTimeInMilliseconds) {
            long seconds = leftTimeInMilliseconds / 1000;
            barTimer.setProgress((int)seconds);
            textTimer.setText(String.format("%02d", seconds/60) + ":" + String.format("%02d", seconds%60));
            // format the textview to show the easily readable format

        }
        @Override
        public void onFinish() {
            if(textTimer.getText().equals("00:00")){
                textTimer.setText("STOP"); 
            }
            else{
                textTimer.setText("2:00");
                barTimer.setProgress(60*minuti);
            }
        }
    }.start();

}  

回答by Melquiades

For creating custom components, please check Android API Guide. Excerpt for Basic Approach:

要创建自定义组件,请查看Android API 指南。基本方法摘录:

  1. Extend an existing View class or subclass with your own class.
  2. Override some of the methods from the superclass. The superclass methods to override start with 'on', for example, onDraw(), onMeasure(), and onKeyDown(). This is similar to the on... events in Activity or ListActivity that you override for lifecycle and other functionality hooks.
  3. Use your new extension class. Once completed, your new extension class can be used in place of the view upon which it was based.
  1. 使用您自己的类扩展现有的 View 类或子类。
  2. 覆盖超类中的一些方法。要覆盖的超类方法以“on”开头,例如 onDraw()、onMeasure() 和 onKeyDown()。这类似于您为生命周期和其他功能挂钩覆盖的 Activity 或 ListActivity 中的 on... 事件。
  3. 使用您的新扩展类。完成后,您的新扩展类可以用来代替它所基于的视图。

Also, check Todd Davies' Progress Wheel at https://github.com/Todd-Davies/ProgressWheel, this should get you started.

另外,请在https://github.com/Todd-Davies/ProgressWheel 上查看 Todd Davies 的 Progress Wheel ,这应该可以帮助您入门。

回答by suresh madaparthi

Smooth circle progress bar timer

平滑圆圈进度条计时器

XML Layout:

XML 布局:

activity_main

活动主

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:id="@+id/reativelayout"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:fitsSystemWindows="true">

<ProgressBar
    android:id="@+id/progressbar_timerview"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="260dp"
    android:layout_height="260dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_gravity="center_horizontal|bottom"
    android:indeterminate="false"
    android:progressDrawable="@drawable/circleshape2_timerview" />

 <TextView
    android:id="@+id/textView_timerview_time"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:alpha="0.6"
    android:background="@drawable/circleshape_timerview"
    android:gravity="center"
    android:text="00:00"
    android:textColor="@android:color/black"
    android:textSize="20sp"
    android:textStyle="bold" />

 <ProgressBar
    android:id="@+id/progressbar1_timerview"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="260dp"
    android:layout_height="260dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_gravity="center_horizontal|center"
    android:indeterminate="false"
    android:progressDrawable="@drawable/circleshape1_timerview"
    android:visibility="gone" />

<Button
    android:id="@+id/button_timerview_start"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_centerHorizontal="true"
    android:background="@android:color/transparent"
    android:text="Start !"
    android:textAllCaps="false"
    android:textSize="20sp"
    android:textStyle="italic" />


 <Button
    android:id="@+id/button_timerview_stop"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_centerHorizontal="true"
    android:background="@android:color/transparent"
    android:text="Stop !"
    android:layout_marginTop="30dp"
    android:textAllCaps="false"
    android:textSize="20sp"
    android:visibility="invisible"
    android:textStyle="italic"
    />

<EditText
    android:id="@+id/textview_timerview_back"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:gravity="center"
    android:padding="5dp"
    android:layout_marginBottom="30dp"
    android:textSize="35sp"
    android:hint=""/>
  </RelativeLayout>

Drawable file:

可绘制文件:

circleshape2_timerview

circleshape2_timerview

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/progress">
        <shape
            android:innerRadiusRatio="5"
            android:shape="ring"
            android:thicknessRatio="20.0"

            android:useLevel="false"
            android:visible="true">
            <gradient
                android:centerColor="#FF00"
                android:endColor="#FF00"
                android:startColor="#FF00ff"
                android:type="sweep" />
        </shape>
    </item>
</layer-list>

circleshape1_timerview

circleshape1_timerview

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/progress">
        <rotate
            android:fromDegrees="270"
            android:toDegrees="-90">
            <shape
                android:innerRadiusRatio="5"
                android:shape="ring"
                android:thicknessRatio="20.0"

                android:useLevel="true"
                android:visible="true">
                <gradient
                    android:centerColor="#FF00"
                    android:endColor="#FF00"
                    android:startColor="#FF00ff"
                    android:type="sweep" />
            </shape>
        </rotate>

    </item>
</layer-list>

circleshape_timerview

circleshape_timerview

 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item>
    <shape android:shape="oval">

        <solid android:color="#bbb"/>
    </shape>
 </item>
 </selector>

Activity:

活动:

MainActivity

主要活动

 import android.app.Activity;
 import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;

 public class MainActivity extends Activity implements OnClickListener {

int i = -1;
ProgressBar mProgressBar, mProgressBar1;

private Button buttonStartTime, buttonStopTime;
private EditText edtTimerValue;
private TextView textViewShowTime;
private CountDownTimer countDownTimer;
private long totalTimeCountInMilliseconds;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    buttonStartTime = (Button) findViewById(R.id.button_timerview_start);
    buttonStopTime = (Button) findViewById(R.id.button_timerview_stop);

    textViewShowTime = (TextView)  
    findViewById(R.id.textView_timerview_time);
    edtTimerValue = (EditText) findViewById(R.id.textview_timerview_back);

    buttonStartTime.setOnClickListener(this);
    buttonStopTime.setOnClickListener(this);

    mProgressBar = (ProgressBar) findViewById(R.id.progressbar_timerview);
    mProgressBar1 = (ProgressBar) findViewById(R.id.progressbar1_timerview);

  }
  @Override
  public void onClick(View v) {
    if (v.getId() == R.id.button_timerview_start) {

        setTimer();

        buttonStartTime.setVisibility(View.INVISIBLE);
        buttonStopTime.setVisibility(View.VISIBLE);
        mProgressBar.setVisibility(View.INVISIBLE);

        startTimer();
        mProgressBar1.setVisibility(View.VISIBLE);


    } else if (v.getId() == R.id.button_timerview_stop) {
        countDownTimer.cancel();
        countDownTimer.onFinish();
        mProgressBar1.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.VISIBLE);
        edtTimerValue.setVisibility(View.VISIBLE);
        buttonStartTime.setVisibility(View.VISIBLE);
        buttonStopTime.setVisibility(View.INVISIBLE);
    }
 }
  private void setTimer(){
    int time = 0;
    if (!edtTimerValue.getText().toString().equals("")) {
        time = Integer.parseInt(edtTimerValue.getText().toString());
    } else
        Toast.makeText(MainActivity.this, "Please Enter Minutes...",  
  Toast.LENGTH_LONG).show();
    totalTimeCountInMilliseconds =  time * 1000;
    mProgressBar1.setMax( time * 1000);
   }
   private void startTimer() {
    countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 1) {
        @Override
        public void onTick(long leftTimeInMilliseconds) {
            long seconds = leftTimeInMilliseconds / 1000;
            mProgressBar1.setProgress((int) (leftTimeInMilliseconds));

            textViewShowTime.setText(String.format("%02d", seconds / 60)
                    + ":" + String.format("%02d", seconds % 60));
        }
        @Override
        public void onFinish() {
            textViewShowTime.setText("00:00");
            textViewShowTime.setVisibility(View.VISIBLE);
            buttonStartTime.setVisibility(View.VISIBLE);
            buttonStopTime.setVisibility(View.VISIBLE);
            mProgressBar.setVisibility(View.VISIBLE);
            mProgressBar1.setVisibility(View.GONE);

        }
    }.start();
 }
 }