Come personalizzare una barra di avanzamento in Android


160

Sto lavorando su un'app in cui voglio mostrare un ProgressBar, ma voglio sostituire Android predefinito ProgressBar.

Quindi, come posso personalizzare il ProgressBar?

Ho bisogno di grafica e animazione per questo?

Ho letto il seguente post ma non sono riuscito a farlo funzionare:

Barra di avanzamento personalizzata Android


1
Prova questa barra di avanzamento personalizzata è ProgressWheel
neeraj kirola,

Risposte:


300

La personalizzazione di a ProgressBarrichiede la definizione dell'attributo o delle proprietà per lo sfondo e l'avanzamento della barra di avanzamento.

Crea un file XML chiamato customprogressbar.xmlnella tua res->drawablecartella:

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> 

Ora devi impostare la progressDrawableproprietà in customprogressbar.xml(disegnabile)

Puoi farlo nel file XML o nell'attività (in fase di esecuzione).

Procedi come segue nel tuo 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" />

In fase di esecuzione, procedere come segue

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

Modifica: layout xml corretto


5
cosa è res ?? res.getDrawable not found
hiren gamit

1
@hirengamit res è "Risorsa". Probabilmente l'errore indica che non è stato possibile trovare il file. "C: /whereYourProjectFolderIs/res/drawable/customprogressbar.xml" <- impossibile trovare. Se è lì, prova a "ripulire" il tuo progetto, rimodella il file di risorse.
K - La tossicità in SO sta crescendo.

5
@Johnson, res sta per Resource. Se si sostituisce la linea in Drawable draw = getResources (). GetDrawable (R.drawable.custom_progressbar); dovrebbe funzionare.
Erwin Lengkeek,

7
Perché è necessario impostare i progressi disegnabili in fase di esecuzione, quando è possibile farlo sul file XML?
Nicolás Arias,

1
@ NicolásArias forse vuoi cambiarne l'aspetto, per qualsiasi motivo possibile (es. Passare dal verde come in "attesa di risposta" al rosso come in "attesa di gestione degli errori")
ocramot

35

In caso di complessi ProgressBarcome questo,

inserisci qui la descrizione dell'immagine

usare ClipDrawable.

NOTA: non ho usato ProgressBarqui in questo esempio. Ho raggiunto questo obiettivo usando ClipDrawable tagliando l'immagine con Animation.

A Drawableche ne ritaglia un altro in Drawablebase al Drawablevalore di livello corrente di questo. Puoi controllare quanto il bambino Drawableviene troncato in larghezza e altezza in base al livello, nonché una gravità per controllare dove è collocato nel suo contenitore generale. Most often used to implement things like progress bars, aumentando il livello del disegno con setLevel().

NOTA: il disegno è completamente tagliato e non visibile quando il livello è 0 e completamente rivelato quando il livello è 10.000.

Ho usato queste due immagini per farlo 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" />

In caso di complessi HorizontalProgressBarbasta cambiare cliporientationin clip_source.xml in questo modo,

android:clipOrientation="horizontal"

Puoi scaricare la demo completa da qui .


il codice è davvero interessante ma mi dà un'eccezione nullpointer sull'oggetto img:
Parth Anjaria

Trova l'ID del widget, l'eccezione verrà risolta.
Vikash Sharma,

34

nel tuo xml

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

E in 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>

Ed custom_progress_bar_horizontalè un XML archiviato in una cartella disegnabile che definisce la barra di avanzamento personalizzata. Per maggiori dettagli vedi questo blog .

Spero che questo ti possa aiutare.


10

La personalizzazione del colore della barra di avanzamento, in particolare nel caso del tipo di spinner, richiede un file xml e l'avvio di codici nei rispettivi file java.

Crea un file xml e chiamalo 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>

Usa il seguente codice per ottenere la filatrice in vari colori previsti. Qui usiamo il codice esadecimale per visualizzare la filatrice in colore blu.

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

Esiste un modo per impostare questo filtro colore per l'intera app, intendo, in ogni barra di avanzamento, come impostarlo in stili o sth? thnx
Hugo

8

Esistono due tipi di barre di avanzamento denominate barra di avanzamento determinata (durata fissa) e barra di avanzamento indeterminata (durata sconosciuta).

I drawable per entrambi i tipi di barra di avanzamento possono essere personalizzati definendo drawable come risorsa xml. Puoi trovare ulteriori informazioni sugli stili della barra di avanzamento e sulla personalizzazione su http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples .

Personalizzazione della barra di avanzamento fissa o orizzontale:

Sotto xml è presente una risorsa di disegno per la personalizzazione della barra di avanzamento orizzontale.

 <?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>

Personalizzazione della barra di avanzamento indeterminata

Sotto xml è presente una risorsa di disegno per la personalizzazione della barra di avanzamento circolare.

<?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>

5

Creazione di ProgressBar personalizzata come hotstar.

  1. Aggiungi la barra di avanzamento sul file di layout e imposta l'indeterminateDrawable con il file drawable.

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. Crea un nuovo file XML in 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>

4

Il modo più semplice per creare personalizzare una barra di avanzamento in Android:

  1. Inizializza e mostra la finestra di dialogo:

    MyProgressDialog progressdialog = new MyProgressDialog(getActivity());
    progressdialog.show();
  2. Crea metodo:

    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. Crea XML di layout:

    <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. Crea forma progresscustombg.xml e inserisci 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>

3

Per utilizzare un disegno personalizzato:

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

(aggiungi sotto res / drawable progress.xml). my_drawablepuò essere xml, png

Quindi nel layout utilizzare

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

1
Questa è la migliore risposta che io abbia mai visto. Funziona come il fascino. Grazie
Rajeshwar,

1

Se vuoi farlo nel codice, ecco un esempio:

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

L'uso di TextView ti dà un'opzione per cambiare colore, dimensione e carattere del tuo testo. Altrimenti puoi semplicemente chiamare setMessage (), come al solito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.