如何在 Android 中自定义进度条

Posted

技术标签:

【中文标题】如何在 Android 中自定义进度条【英文标题】:How to Customize a Progress Bar In Android 【发布时间】:2013-05-29 09:29:34 【问题描述】:

我正在开发一个应用程序,我想在其中显示 ProgressBar,但我想替换默认的 android ProgressBar

那么如何自定义ProgressBar

我需要一些图形和动画吗?

我阅读了以下帖子,但无法正常工作:

Custom Progress bar Android

【问题讨论】:

试试这个自定义进度条是ProgressWheel 【参考方案1】:

自定义ProgressBar 需要为进度条的背景和进度定义一个或多个属性。

在您的 res->drawable 文件夹中创建一个名为 customprogressbar.xml 的 XML 文件:

custom_progressbar.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Define the background properties like color etc -->
    <item android:id="@android:id/background">
    <shape>
        <gradient
                android:startColor="#000001"
                android:centerColor="#0b131e"
                android:centerY="1.0"
                android:endColor="#0d1522"
                android:angle="270"
        />
    </shape>
   </item>

  <!-- Define the progress properties like start color, end color etc -->
  <item android:id="@android:id/progress">
    <clip>
        <shape>
            <gradient
                android:startColor="#007A00"
                android:centerColor="#007A00"
                android:centerY="1.0"
                android:endColor="#06101d"
                android:angle="270"
            />
        </shape>
    </clip>
    </item>
</layer-list> 

现在你需要在customprogressbar.xml (drawable) 中设置progressDrawable 属性

您可以在 XML 文件或 Activity 中(在运行时)执行此操作。

在您的 XML 中执行以下操作:

<ProgressBar
    android:id="@+id/progressBar1"
    style="?android:attr/progressBarStyleHorizontal"
    android:progressDrawable="@drawable/custom_progressbar"         
    android:layout_
    android:layout_ />

在运行时执行以下操作

// Get the Drawable custom_progressbar                     
    Drawable draw=res.getDrawable(R.drawable.custom_progressbar);
// set the drawable as progress drawable
    progressBar.setProgressDrawable(draw);

编辑:更正了 xml 布局

【讨论】:

什么是 res ?? res.getDrawable 未找到 @hirengamit res 是“资源”。您的错误可能表明找不到该文件。 "C:/whereYourProjectFolderIs/res/drawable/customprogressbar.xml" @Johnson , res 代表资源。如果将行替换为 Drawable draw = getResources().getDrawable(R.drawable.custom_progressbar);它应该可以工作。 为什么必须在运行时设置可绘制的进度,而可以在 xml 文件上进行设置? @NicolásArias 也许你想改变它的外观,出于任何可能的原因(例如,从“等待响应”中的绿色变为“等待错误处理”中的红色)【参考方案2】:

如果像这样复杂的ProgressBar

使用ClipDrawable

注意:在这个例子中我没有使用ProgressBar。我已经达到 这使用ClipDrawable 通过使用Animation 剪切图像。

一个Drawable 根据这个Drawable 的当前电平值剪辑另一个Drawable。您可以根据级别控制子 Drawable 在宽度和高度上被裁剪的程度,以及控制其在整个容器中放置位置的重力。 Most often used to implement things like progress bars,通过使用 setLevel() 增加可绘制对象的级别。

注意:drawable 被完全裁剪,当 level 为 0 时不可见 并在10000级时完全显示。

我用这两张图片制作了这个CustomProgressBar

scall.png

ballon_progress.png

MainActivity.java

public class MainActivity extends ActionBarActivity 

private EditText etPercent;
private ClipDrawable mImageDrawable;

// a field in your class
private int mLevel = 0;
private int fromLevel = 0;
private int toLevel = 0;

public static final int MAX_LEVEL = 10000;
public static final int LEVEL_DIFF = 100;
public static final int DELAY = 30;

private Handler mUpHandler = new Handler();
private Runnable animateUpImage = new Runnable() 

    @Override
    public void run() 
        doTheUpAnimation(fromLevel, toLevel);
    
;

private Handler mDownHandler = new Handler();
private Runnable animateDownImage = new Runnable() 

    @Override
    public void run() 
        doTheDownAnimation(fromLevel, toLevel);
    
;

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

    etPercent = (EditText) findViewById(R.id.etPercent);

    ImageView img = (ImageView) findViewById(R.id.imageView1);
    mImageDrawable = (ClipDrawable) img.getDrawable();
    mImageDrawable.setLevel(0);


private void doTheUpAnimation(int fromLevel, int toLevel) 
    mLevel += LEVEL_DIFF;
    mImageDrawable.setLevel(mLevel);
    if (mLevel <= toLevel) 
        mUpHandler.postDelayed(animateUpImage, DELAY);
     else 
        mUpHandler.removeCallbacks(animateUpImage);
        MainActivity.this.fromLevel = toLevel;
    


private void doTheDownAnimation(int fromLevel, int toLevel) 
    mLevel -= LEVEL_DIFF;
    mImageDrawable.setLevel(mLevel);
    if (mLevel >= toLevel) 
        mDownHandler.postDelayed(animateDownImage, DELAY);
     else 
        mDownHandler.removeCallbacks(animateDownImage);
        MainActivity.this.fromLevel = toLevel;
    


public void onClickOk(View v) 
    int temp_level = ((Integer.parseInt(etPercent.getText().toString())) * MAX_LEVEL) / 100;

    if (toLevel == temp_level || temp_level > MAX_LEVEL) 
        return;
    
    toLevel = (temp_level <= MAX_LEVEL) ? temp_level : toLevel;
    if (toLevel > fromLevel) 
        // cancel previous process first
        mDownHandler.removeCallbacks(animateDownImage);
        MainActivity.this.fromLevel = toLevel;

        mUpHandler.post(animateUpImage);
     else 
        // cancel previous process first
        mUpHandler.removeCallbacks(animateUpImage);
        MainActivity.this.fromLevel = toLevel;

        mDownHandler.post(animateDownImage);
    


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:orientation="vertical"
tools:context=".MainActivity">

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="horizontal">

    <EditText
        android:id="@+id/etPercent"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:inputType="number"
        android:maxLength="3" />

    <Button
        android:layout_
        android:layout_
        android:text="Ok"
        android:onClick="onClickOk" />

</LinearLayout>

<FrameLayout
    android:layout_
    android:layout_
    android:layout_gravity="center">

    <ImageView
        android:id="@+id/imageView2"
        android:layout_
        android:layout_
        android:src="@drawable/scall" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_
        android:layout_
        android:src="@drawable/clip_source" />

</FrameLayout>

clip_source.xml

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/ballon_progress"
    android:gravity="bottom" />

如果是复杂的HorizontalProgressBar,只需像这样在clip_source.xml中更改cliporientation

android:clipOrientation="horizontal"

您可以从here下载完整的演示。

【讨论】:

代码真的很有趣,但它给了我 img 对象上的空指针异常: 找到widget的id,你的异常就解决了。【参考方案3】:

在你的 xml 中

<ProgressBar
        android:id="@+id/progressBar1"
        android:layout_
        android:layout_
        style="@style/CustomProgressBar" 
        android:layout_margin="5dip" />

res/values/styles.xml:

<resources> 
        <style name="CustomProgressBar" parent="android:Widget.ProgressBar.Horizontal">
          <item name="android:indeterminateOnly">false</item>
          <item name="android:progressDrawable">@drawable/custom_progress_bar_horizontal</item>
          <item name="android:minHeight">10dip</item>
          <item name="android:maxHeight">20dip</item>
        </style>       
    <style name="AppTheme" parent="android:Theme.Light" />
</resources>

custom_progress_bar_horizontal 是一个存储在可绘制文件夹中的 xml,它定义了您的自定义进度条。有关更多详细信息,请参阅blog。

希望对你有帮助。

【讨论】:

【参考方案4】:

自定义进度条的颜色,即在 spinner 类型需要 xml 文件并在其各自的 java 文件中启动代码的情况下。

创建一个xml文件并将其命名为progressbar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:gravity="center"
    tools:context=".Radio_Activity" >

    <LinearLayout
        android:id="@+id/progressbar"
        android:layout_
        android:layout_ >

        <ProgressBar
            android:id="@+id/spinner"
            android:layout_
            android:layout_ >
        </ProgressBar>
    </LinearLayout>

</LinearLayout>

使用以下代码获取各种预期颜色的微调器。这里我们使用十六进制代码以蓝色显示微调器。

Progressbar spinner = (ProgressBar) progrees.findViewById(R.id.spinner);
spinner.getIndeterminateDrawable().setColorFilter(Color.parseColor("#80DAEB"),
                android.graphics.PorterDuff.Mode.MULTIPLY);

【讨论】:

有没有办法为整个应用程序设置这个颜色过滤器,我的意思是,在每个进度条中,比如设置它的样式或某事?谢谢【参考方案5】:

有两种类型的进度条,称为确定进度条(固定持续时间)和不确定进度条(未知持续时间)。

可以通过将drawable定义为xml资源来自定义两种类型的进度条的drawable。您可以在http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples 找到有关进度条样式和自定义的更多信息。

自定义固定或水平进度条:

xml下面是水平进度条自定义的可绘制资源。

 <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background"
        android:gravity="center_vertical|fill_horizontal">
        <shape android:shape="rectangle"
            android:tint="?attr/colorControlNormal">
            <corners android:radius="8dp"/>
            <size android: />
            <solid android:color="#90caf9" />
        </shape>
    </item>
    <item android:id="@android:id/progress"
        android:gravity="center_vertical|fill_horizontal">
        <scale android:scaleWidth="100%">
            <shape android:shape="rectangle"
                android:tint="?attr/colorControlActivated">
                <corners android:radius="8dp"/>
                <size android: />
                <solid android:color="#b9f6ca" />
            </shape>
        </scale>
    </item>
</layer-list>

自定义不确定进度条

xml下面是一个可绘制的资源,用于圆形进度条自定义。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/progress"
        android:top="16dp"
        android:bottom="16dp">
                <rotate
                    android:fromDegrees="45"
                    android:pivotX="50%"
                    android:pivotY="50%"
                    android:toDegrees="315">
                    <shape android:shape="rectangle">
                        <size
                            android:
                            android: />
                        <stroke
                            android:
                            android:color="#b71c1c" />
                    </shape>
                </rotate>           
    </item>
</layer-list>

【讨论】:

【参考方案6】:

像 hotstar 一样创建自定义 ProgressBar。

    在布局文件上添加进度条,并用drawable文件设置indeterminateDrawable。

activity_main.xml

<ProgressBar
    style="?android:attr/progressBarStyleLarge"
    android:layout_
    android:layout_
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/player_progressbar"
    android:indeterminateDrawable="@drawable/custom_progress_bar"
    />
    在 res\drawable 中创建新的 xml 文件

custom_progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
    <rotate  xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="1080" >

    <shape
        android:innerRadius="35dp"
        android:shape="ring"
        android:thickness="3dp"
        android:useLevel="false" >
       <size
           android:
           android: />

       <gradient
            android:centerColor="#80b7b4b2"
            android:centerY="0.5"
            android:endColor="#f4eef0"
            android:startColor="#00938c87"
            android:type="sweep"
            android:useLevel="false" />
    </shape>

</rotate>

【讨论】:

【参考方案7】:

使用自定义drawable:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:drawable="@drawable/my_drawable"
android:pivotX="50%"
android:pivotY="50%" />

(在 res/drawable 下添加progress.xml)。 my_drawable 可能是xml、png

然后在你的布局中使用

<ProgressBar
        android:id="@+id/progressBar"
        android:indeterminateDrawable="@drawable/progress_circle"
...
/>

【讨论】:

这是我见过的最好的答案。像魅力一样工作。谢谢【参考方案8】:

在 Android 中创建自定义进度条的最简单方法:

    初始化并显示对话框:

    MyProgressDialog progressdialog = new MyProgressDialog(getActivity());
    progressdialog.show();
    

    创建方法:

    public class MyProgressDialog extends AlertDialog 
          public MyProgressDialog(Context context) 
              super(context);
              getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
          
    
          @Override
          public void show() 
              super.show();
              setContentView(R.layout.dialog_progress);
          
    
    

    创建布局 XML:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_
      android:layout_
      android:background="@android:color/transparent"
      android:clickable="true">
    
        <RelativeLayout
             android:layout_
             android:layout_
             android:layout_centerInParent="true">
    
          <ProgressBar
             android:id="@+id/progressbarr"
             android:layout_
             android:layout_
             android:layout_centerInParent="true"
            android:indeterminateDrawable="@drawable/progresscustombg" />
    
          <TextView
             android:layout_
             android:layout_
             android:layout_centerHorizontal="true"
             android:layout_below="@+id/progressbarr"
             android:layout_marginTop="@dimen/_3sdp"
             android:textColor="@color/white"
             android:text="Please wait"/>
        </RelativeLayout>
    </RelativeLayout>
    

    创建shape progresscustombg.xml并放入res/drawable:

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
      android:fromDegrees="0"
      android:pivotX="50%"
      android:pivotY="50%"
      android:toDegrees="360" >
    
        <shape
           android:innerRadiusRatio="3"
           android:shape="ring"
           android:thicknessRatio="20"
           android:useLevel="false" >
            <size
                android:
                android: />
    
            <gradient
                android:centerY="0.50"
                android:endColor="@color/color_green_icash"
                android:startColor="#FFFFFF"
                android:type="sweep"
                android:useLevel="false" />
        </shape>
    
    </rotate>
    

【讨论】:

【参考方案9】:

如果您想在代码中执行此操作,这里有一个示例:

pd = new ProgressDialog(MainActivity.this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
pd.getWindow().setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);
TextView tv = new TextView(this);
tv.setTextColor(Color.WHITE);
tv.setTextSize(20);
tv.setText("Waiting...");
pd.setCustomTitle(tv);
pd.setIndeterminate(true);
pd.show();

使用 TextView 可以让您选择更改文本的颜色、大小和字体。否则你可以像往常一样调用 setMessage()。

【讨论】:

【参考方案10】:
<ProgressBar
    android:indeterminateDrawable="@drawable/loading"
    style="?android:attr/progressBarStyleLarge"
    android:layout_gravity="center"
    android:layout_
    android:layout_
    android:scaleY="0.5"
    android:scaleX="0.5"
    android:id="@+id/progressBarGallery"/>

@drawable/loadingsrc\main\res\drawable\loading.gif 文件,其大小为200 x 200

【讨论】:

以上是关于如何在 Android 中自定义进度条的主要内容,如果未能解决你的问题,请参考以下文章

使用 Xamarin Forms 在 UWP 中自定义进度条颜色

如何在 Android 应用中自定义顶部状态栏?

如何在Android中制作这个进度条? [关闭]

长按如何使进度条变化Android

android Service中自定义的Binder如何操作service中的handler

如何给progressbar圆形进度条设置颜色