Comment personnaliser une barre de progression sous Android

160

Je travaille sur une application dans laquelle je souhaite afficher un ProgressBar, mais je souhaite remplacer l'Android par défaut ProgressBar.

Alors, comment puis-je personnaliser le ProgressBar?

Ai-je besoin de graphiques et d'animations pour cela?

J'ai lu le post suivant mais je n'ai pas pu le faire fonctionner:

Barre de progression personnalisée Android

Shubham Suryawanshi
la source
1
Essayez cette barre de progression personnalisée est ProgressWheel
neeraj kirola

Réponses:

300

La personnalisation d'un ProgressBarnécessite la définition de l'attribut ou des propriétés de l'arrière-plan et de la progression de votre barre de progression.

Créez un fichier XML nommé customprogressbar.xmldans votre res->drawabledossier:

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> 

Vous devez maintenant définir la progressDrawablepropriété dans customprogressbar.xml(drawable)

Vous pouvez le faire dans le fichier XML ou dans l'activité (au moment de l'exécution).

Procédez comme suit dans votre 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" />

Au moment de l'exécution, procédez comme suit

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

Edit: mise en page XML corrigée

Martijn Pieters
la source
5
qu'est-ce que res ?? res.getDrawable not found
hiren gamit
1
@hirengamit res est "Ressource". Votre erreur indique probablement que le fichier est introuvable. "C: /whereYourProjectFolderIs/res/drawable/customprogressbar.xml" <- est introuvable. S'il est là, essayez de "nettoyer" votre projet, il refait le fichier de ressources.
K - La toxicité du SO augmente.
5
@Johnson, res signifie Ressource. Si vous remplacez la ligne par Drawable draw = getResources (). GetDrawable (R.drawable.custom_progressbar); ça devrait marcher.
Erwin Lengkeek
7
Pourquoi est-il nécessaire de définir la progression dessinable au moment de l'exécution, alors qu'il est possible de le faire sur le fichier xml?
Nicolás Arias
1
@ NicolásArias peut-être voulez-vous changer son apparence, pour n'importe quelle raison possible (par exemple passer du vert comme dans "en attente de réponse" au rouge comme dans "en attente de traitement des erreurs")
ocramot
35

En cas de complexe ProgressBarcomme celui-ci,

entrez la description de l'image ici

utiliser ClipDrawable.

REMARQUE: je n'ai pas utilisé ProgressBarici dans cet exemple. J'ai réalisé cela en utilisant ClipDrawable en coupant l'image avec Animation.

A Drawablequi en coupe un autre en Drawablefonction de Drawablela valeur de niveau actuelle de ce dernier. Vous pouvez contrôler à quel point l'enfant Drawableest coupé en largeur et en hauteur en fonction du niveau, ainsi qu'une gravité pour contrôler où il est placé dans son conteneur global. Most often used to implement things like progress bars, en augmentant le niveau du dessinable avec setLevel().

REMARQUE: le dessin est complètement coupé et non visible lorsque le niveau est à 0 et entièrement révélé lorsque le niveau est de 10 000.

J'ai utilisé ces deux images pour faire cela 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 cas de complexe HorizontalProgressBarchangement juste cliporientationà clip_source.xml comme celui - ci,

android:clipOrientation="horizontal"

Vous pouvez télécharger la démo complète ici .

Jaydipsinh Zala
la source
le code est vraiment intéressant mais il me donne une exception nullpointer sur l'objet img:
Parth Anjaria
Trouvez l'ID du widget, votre exception sera résolue.
Vikash Sharma
34

dans votre xml

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

Et dans 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>

Et custom_progress_bar_horizontalest un xml stocké dans un dossier dessinable qui définit votre barre de progression personnalisée. Pour plus de détails, consultez ce blog .

J'espère que cela t'aidera.

Gunaseelan
la source
10

La personnalisation de la couleur de la barre de progression, notamment en cas de type spinner, nécessite un fichier xml et des codes d'initiation dans leurs fichiers java respectifs.

Créez un fichier xml et nommez-le 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>

Utilisez le code suivant pour obtenir le spinner dans diverses couleurs attendues. Ici, nous utilisons le code hexadécimal pour afficher le spinner en bleu.

Progressbar spinner = (ProgressBar) progrees.findViewById(R.id.spinner);
spinner.getIndeterminateDrawable().setColorFilter(Color.parseColor("#80DAEB"),
                android.graphics.PorterDuff.Mode.MULTIPLY);
user4125837
la source
Existe-t-il un moyen de définir ce filtre de couleur pour l'ensemble de l'application, je veux dire, dans chaque barre de progression, comme le définir dans les styles ou qc? thnx
Hugo
8

Il existe deux types de barres de progression appelées barre de progression déterminée (durée fixe) et barre de progression indéterminée (durée inconnue).

Les dessinables pour les deux types de barre de progression peuvent être personnalisés en définissant drawable comme ressource XML. Vous pouvez trouver plus d'informations sur les styles et la personnalisation de la barre de progression à l' adresse http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples .

Personnalisation de la barre de progression fixe ou horizontale:

Ci-dessous xml se trouve une ressource dessinable pour la personnalisation de la barre de progression horizontale.

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

Personnalisation de la barre de progression indéterminée

Ci-dessous xml se trouve une ressource dessinable pour la personnalisation de la barre de progression circulaire.

<?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
la source
5

Création d'une barre de progression personnalisée comme hotstar.

  1. Ajoutez la barre de progression sur le fichier de mise en page et définissez le indeterminateDrawable avec le fichier dessinable.

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. Créer un nouveau fichier xml dans 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
la source
4

Le moyen le plus simple de créer une barre de progression personnalisée sous Android:

  1. Initialiser et afficher la boîte de dialogue:

    MyProgressDialog progressdialog = new MyProgressDialog(getActivity());
    progressdialog.show();
  2. Créer une méthode:

    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. Créer une mise en page 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. Créez la forme progresscustombg.xml et mettez 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
la source
3

Pour utiliser un dessin personnalisé:

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

(ajouter sous res / drawable progress.xml). my_drawablepeut être xml, png

Ensuite, dans votre mise en page, utilisez

<ProgressBar
        android:id="@+id/progressBar"
        android:indeterminateDrawable="@drawable/progress_circle"
...
/>
Evgenii Vorobei
la source
1
C'est la meilleure réponse que j'aie jamais vue. Fonctionne comme du charme. Merci
Rajeshwar
1

Si vous souhaitez le faire dans le code, voici un exemple:

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'utilisation de TextView vous donne la possibilité de changer la couleur, la taille et la police de votre texte. Sinon, vous pouvez simplement appeler setMessage (), comme d'habitude.

Flot2011
la source