Cómo personalizar una barra de progreso en Android

160

Estoy trabajando en una aplicación en la que quiero mostrar un ProgressBar, pero quiero reemplazar el Android predeterminado ProgressBar.

Entonces, ¿cómo puedo personalizar el ProgressBar?

¿Necesito algunos gráficos y animación para eso?

Leí la siguiente publicación pero no pude hacerlo funcionar:

Barra de progreso personalizada Android

Shubham Suryawanshi
fuente
1
Pruebe esta barra de progreso personalizada es ProgressWheel
neeraj kirola

Respuestas:

300

Personalizar un ProgressBarrequiere definir el atributo o las propiedades para el fondo y el progreso de su barra de progreso.

Cree un archivo XML con nombre customprogressbar.xmlen su res->drawablecarpeta:

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> 

Ahora necesita establecer la progressDrawablepropiedad en customprogressbar.xml(dibujable)

Puede hacer esto en el archivo XML o en la Actividad (en tiempo de ejecución).

Haga lo siguiente en su XML:

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

En tiempo de ejecución, haga lo siguiente

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

Editar: diseño xml corregido

Martijn Pieters
fuente
55
¿Qué es res? res.getDrawable no encontrado
hiren gamit
1
@hirengamit res es "Recurso". Su error probablemente indica que no se puede encontrar el archivo. "C: /whereYourProjectFolderIs/res/drawable/customprogressbar.xml" <- no se puede encontrar. Si está allí, intente "limpiar" su proyecto, rehace el archivo de recursos.
K - La toxicidad en SO está creciendo.
55
@Johnson, res significa Resource. Si reemplaza la línea a Drawable draw = getResources (). GetDrawable (R.drawable.custom_progressbar); deberia de funcionar.
Erwin Lengkeek
77
¿Por qué es necesario establecer el progreso dibujable en tiempo de ejecución, cuando es posible hacerlo en el archivo xml?
Nicolás Arias
1
@ NicolásArias tal vez desee cambiar su apariencia, por cualquier motivo posible (por ejemplo, cambiar de verde como "esperando respuesta" a rojo como "esperando manejo de errores")
ocramot
35

En caso de complejos ProgressBarcomo este,

ingrese la descripción de la imagen aquí

uso ClipDrawable.

NOTA: No he usado ProgressBaraquí en este ejemplo. He logrado esto usando ClipDrawable al recortar la imagen con Animation.

A Drawableque recorta otro en Drawablefunción del Drawablevalor de nivel actual de este. Puede controlar cuánto se corta el niño Drawableen ancho y alto según el nivel, así como la gravedad para controlar dónde se coloca en su contenedor general. Most often used to implement things like progress bars, aumentando el nivel del sorteo con setLevel().

NOTA: El sorteo se recorta completamente y no es visible cuando el nivel es 0 y se revela completamente cuando el nivel es 10,000.

He usado estas dos imágenes para hacer esto CustomProgressBar.

scall.png

scall.png

ballon_progress.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_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:orientation="vertical"
tools:context=".MainActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <EditText
        android:id="@+id/etPercent"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:inputType="number"
        android:maxLength="3" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Ok"
        android:onClick="onClickOk" />

</LinearLayout>

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/scall" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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" />

En el caso del complejo de HorizontalProgressBarcambio justo cliporientationen clip_source.xml como este,

android:clipOrientation="horizontal"

Puede descargar la demostración completa desde aquí .

Jaydipsinh Zala
fuente
el código es realmente interesante, pero me da una excepción de puntero nulo en el objeto img:
Parth Anjaria
Encuentre la identificación del widget, su excepción será resuelta.
Vikash Sharma
34

en tu xml

<ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="@style/CustomProgressBar" 
        android:layout_margin="5dip" />

Y en 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>

Y custom_progress_bar_horizontales un xml almacenado en una carpeta dibujable que define su barra de progreso personalizada. Para más detalles ver este blog .

Espero que esto ayude.

Gunaseelan
fuente
10

La personalización del color de la barra de progreso, es decir, en el caso del tipo de ruleta, necesita un archivo xml e códigos de inicio en sus respectivos archivos java.

Cree un archivo xml y asígnele el nombre de 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_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    tools:context=".Radio_Activity" >

    <LinearLayout
        android:id="@+id/progressbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <ProgressBar
            android:id="@+id/spinner"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </ProgressBar>
    </LinearLayout>

</LinearLayout>

Use el siguiente código para obtener la ruleta en varios colores esperados. Aquí usamos el código hexadecimal para mostrar la ruleta en color azul.

Progressbar spinner = (ProgressBar) progrees.findViewById(R.id.spinner);
spinner.getIndeterminateDrawable().setColorFilter(Color.parseColor("#80DAEB"),
                android.graphics.PorterDuff.Mode.MULTIPLY);
usuario4125837
fuente
¿Hay alguna forma de configurar este filtro de color para toda la aplicación, es decir, en cada barra de progreso, como configurarlo en estilos o algo? thnx
Hugo
8

Hay dos tipos de barras de progreso llamadas barra de progreso determinada (duración fija) y barra de progreso indeterminada (duración desconocida).

Los elementos dibujables para ambos tipos de barra de progreso se pueden personalizar definiendo dibujable como recurso xml. Puede encontrar más información sobre estilos de barra de progreso y personalización en http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples .

Personalización de la barra de progreso fija u horizontal:

Debajo de xml hay un recurso dibujable para la personalización de la barra de progreso horizontal.

 <?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:height="20dp" />
            <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:height="20dp" />
                <solid android:color="#b9f6ca" />
            </shape>
        </scale>
    </item>
</layer-list>

Personalizar barra de progreso indeterminada

Debajo de xml hay un recurso dibujable para la personalización de la barra de progreso circular.

<?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:width="80dp"
                            android:height="80dp" />
                        <stroke
                            android:width="6dp"
                            android:color="#b71c1c" />
                    </shape>
                </rotate>           
    </item>
</layer-list>
Arnav Rao
fuente
5

Creando ProgressBar personalizado como hotstar.

  1. Agregue la barra de progreso en el archivo de diseño y establezca indeterminateDrawable con archivo dibujable.

activity_main.xml

<ProgressBar
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/player_progressbar"
    android:indeterminateDrawable="@drawable/custom_progress_bar"
    />
  1. Cree un nuevo archivo xml en res \ drawable

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:height="80dp"
           android:width="80dp" />

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

</rotate>
Rajesh Shetty
fuente
4

La forma más sencilla de crear personalizar una barra de progreso en Android:

  1. Inicializar y mostrar diálogo:

    MyProgressDialog progressdialog = new MyProgressDialog(getActivity());
    progressdialog.show();
  2. Crear método:

    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);
          }
    }
  3. Crear diseño XML:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@android:color/transparent"
      android:clickable="true">
    
        <RelativeLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true">
    
          <ProgressBar
             android:id="@+id/progressbarr"
             android:layout_width="@dimen/eightfive"
             android:layout_height="@dimen/eightfive"
             android:layout_centerInParent="true"
            android:indeterminateDrawable="@drawable/progresscustombg" />
    
          <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerHorizontal="true"
             android:layout_below="@+id/progressbarr"
             android:layout_marginTop="@dimen/_3sdp"
             android:textColor="@color/white"
             android:text="Please wait"/>
        </RelativeLayout>
    </RelativeLayout>
  4. Cree la forma progresscustombg.xml y ponga 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:height="@dimen/eightfive"
                android:width="@dimen/eightfive" />
    
            <gradient
                android:centerY="0.50"
                android:endColor="@color/color_green_icash"
                android:startColor="#FFFFFF"
                android:type="sweep"
                android:useLevel="false" />
        </shape>
    
    </rotate>
Jaydeep Dobariya
fuente
3

Para usar dibujable personalizado:

<?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%" />

(agregar bajo res / dibujable progress.xml). my_drawablepuede ser xml, png

Luego, en su diseño, use

<ProgressBar
        android:id="@+id/progressBar"
        android:indeterminateDrawable="@drawable/progress_circle"
...
/>
Evgenii Vorobei
fuente
1
Esta es la mejor respuesta que he visto. Funciona como encanto. Gracias
Rajeshwar
1

Si desea hacer esto en código, aquí hay una muestra:

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();

El uso de TextView le brinda una opción para cambiar el color, el tamaño y la fuente de su texto. De lo contrario, puede llamar a setMessage (), como de costumbre.

Flot2011
fuente