web-dev-qa-db-fra.com

Custom Drawable pour ProgressBar/ProgressDialog

En lisant la documentation limitée fournie par Google, j'ai l’impression qu’il est possible de changer l’aspect (dessinable) d’un ProgressBar/ProgressDialog en créant simplement un nouveau style et en l’affectant à la propriété de style de ProgressBar. Mais je ne peux pas que cela fonctionne correctement. Voici ce que j'ai fait jusqu'à présent:

J'ai créé une forme comme celle-ci (mp2.xml)

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:shape="ring"
  Android:innerRadiusRatio="4"
  Android:thicknessRatio="4"
  Android:useLevel="false">
 <size Android:width="50dip" Android:height="50dip" />
 <gradient Android:type="sweep" Android:useLevel="false" Android:startColor="#300000ff" Android:centerColor="#500000ff" Android:endColor="#ff0000ff" />
</shape>

puis créé une animation (mp3.xml) comme celle-ci:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:oneshot="false">
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="0" Android:toDegrees="30" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="30" Android:toDegrees="60" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="60" Android:toDegrees="90" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="90" Android:toDegrees="120" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="120" Android:toDegrees="150" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="150" Android:toDegrees="180" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="180" Android:toDegrees="210" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="210" Android:toDegrees="240" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="240" Android:toDegrees="270" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="270" Android:toDegrees="300" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="300" Android:toDegrees="330" Android:repeatCount="1" />
 </item>
 <item Android:duration="70">
  <rotate xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:drawable="@drawable/mp2" Android:pivotX="50%" Android:pivotY="50%" Android:fromDegrees="330" Android:toDegrees="360" Android:repeatCount="1" />
 </item>
</animation-list>

puis créé un style (attrs.xml) comme celui-ci:

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style parent="@Android:style/Widget.ProgressBar" name="customProgressBar">
  <item name="Android:progressDrawable">@anim/mp3</item>
 </style>
</resources>

et dans mon main.xml, j'ai défini le style comme suit:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
       Android:orientation="vertical"
       Android:layout_width="fill_parent"
       Android:layout_height="fill_parent" Android:drawingCacheQuality="high">
 <ProgressBar Android:id="@+id/ProgressBar01"
     Android:layout_width="wrap_content"
     Android:layout_height="wrap_content" style="@style/customProgressBar"/>
</LinearLayout>

Mais il montre toujours le même dessin que précédemment. Qu'est-ce que je fais mal?

119
Sam

J'ai utilisé ce qui suit pour créer une barre de progression personnalisée.

Le fichier res/drawable/progress_bar_states.xml déclare les couleurs des différents états:

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

    <item Android:id="@Android:id/background">
        <shape>
            <gradient
                    Android:startColor="#000001"
                    Android:centerColor="#0b131e"
                    Android:centerY="0.75"
                    Android:endColor="#0d1522"
                    Android:angle="270"
            />
        </shape>
    </item>

    <item Android:id="@Android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                        Android:startColor="#234"
                        Android:centerColor="#234"
                        Android:centerY="0.75"
                        Android:endColor="#a24"
                        Android:angle="270"
                />
            </shape>
        </clip>
    </item>

    <item Android:id="@Android:id/progress">
        <clip>
            <shape>
                <gradient
                    Android:startColor="#144281"
                    Android:centerColor="#0b1f3c"
                    Android:centerY="0.75"
                    Android:endColor="#06101d"
                    Android:angle="270"
                />
            </shape>
        </clip>
    </item>

</layer-list>

Et le code à l'intérieur de votre mise en page XML:

<ProgressBar Android:id="@+id/progressBar"
    Android:progressDrawable="@drawable/progress_bar_states"
    Android:layout_width="fill_parent" Android:layout_height="8dip" 
    style="?android:attr/progressBarStyleHorizontal" 
    Android:indeterminateOnly="false" 
    Android:max="100">
</ProgressBar>

Prendre plaisir!

134
Jona

J'avais quelques difficultés à utiliser un dialogue de progression indéterminé avec la solution proposée ici, après quelques travaux et essais et erreurs, j'ai réussi à le faire fonctionner.

Tout d’abord, créez l’animation que vous souhaitez utiliser pour la boîte de dialogue Progression. Dans mon cas, j'ai utilisé 5 images. 

../res/anim/progress_dialog_icon_drawable_animation.xml:

<animation-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@drawable/icon_progress_dialog_drawable_1" Android:duration="150" />
    <item Android:drawable="@drawable/icon_progress_dialog_drawable_2" Android:duration="150" />
    <item Android:drawable="@drawable/icon_progress_dialog_drawable_3" Android:duration="150" />
    <item Android:drawable="@drawable/icon_progress_dialog_drawable_4" Android:duration="150" />
    <item Android:drawable="@drawable/icon_progress_dialog_drawable_5" Android:duration="150" />
</animation-list>

Où vous voulez montrer un ProgressDialog:

dialog = new ProgressDialog(Context.this);
dialog.setIndeterminate(true);
dialog.setIndeterminateDrawable(getResources().getDrawable(R.anim.progress_dialog_icon_drawable_animation));
dialog.setMessage("Some Text");
dialog.show();

Cette solution est très simple et a fonctionné pour moi. Vous pouvez étendre ProgressDialog et lui substituer le caractère dessinable en interne. Cependant, c’était vraiment trop compliqué pour ce que j’avais besoin, je ne l’ai pas fait.

53
blindstuff

Essayez de régler:

Android:indeterminateDrawable="@drawable/progress" 

Cela a fonctionné pour moi. Voici également le code pour progress.xml:

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

    <shape Android:shape="ring" Android:innerRadiusRatio="3"
        Android:thicknessRatio="8" Android:useLevel="false">

        <size Android:width="48dip" Android:height="48dip" />

        <gradient Android:type="sweep" Android:useLevel="false"
            Android:startColor="#4c737373" Android:centerColor="#4c737373"
            Android:centerY="0.50" Android:endColor="#ffffd300" />

    </shape>

</rotate> 
32
mudit

Votre style devrait ressembler à ceci:

<style parent="@Android:style/Widget.ProgressBar" name="customProgressBar">
    <item name="Android:indeterminateDrawable">@anim/mp3</item>
</style>
10
Victor

Progrès personnalisés à l'échelle!

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <item Android:duration="150">
        <scale
            Android:drawable="@drawable/face_no_smile_eyes_off"
            Android:scaleGravity="center" />
    </item>
    <item Android:duration="150">
        <scale
            Android:drawable="@drawable/face_no_smile_eyes_on"
            Android:scaleGravity="center" />
    </item>
    <item Android:duration="150">
        <scale
            Android:drawable="@drawable/face_smile_eyes_off"
            Android:scaleGravity="center" />
    </item>
    <item Android:duration="150">
        <scale
            Android:drawable="@drawable/face_smile_eyes_on"
            Android:scaleGravity="center" />
    </item>

</animation-list>
6
Dmitry

je fais votre code. Je peux courir mais j'ai besoin de modifier deux endroits:

  1. name="Android:indeterminateDrawable" au lieu de Android:progressDrawable 

  2. modifier le nom attrs.xml ---> styles.xml

5
pengwang

Je ne suis pas sûr, mais dans ce cas, vous pouvez toujours utiliser un AlertDialog personnalisé complet en définissant un fichier de présentation distinct dans la boîte de dialogue d'alerte et en définissant l'animation pour votre visualisation en utilisant une partie de votre code ci-dessus qui devrait également le faire!

0
Jayshil Dave
public class CustomProgressBar {
    private RelativeLayout rl;
    private ProgressBar mProgressBar;
    private Context mContext;
    private String color__ = "#FF4081";
    private ViewGroup layout;
    public CustomProgressBar (Context context, boolean isMiddle, ViewGroup layout) {
        initProgressBar(context, isMiddle, layout);
    }

    public CustomProgressBar (Context context, boolean isMiddle) {
        try {
            layout = (ViewGroup) ((Activity) context).findViewById(Android.R.id.content).getRootView();
        } catch (Exception e) {
            e.printStackTrace();
        }
        initProgressBar(context, isMiddle, layout);
    }

    void initProgressBar(Context context, boolean isMiddle, ViewGroup layout) {
        mContext = context;
        if (layout != null) {
            int padding;
            if (isMiddle) {
                mProgressBar = new ProgressBar(context, null, Android.R.attr.progressBarStyleSmall);
                // mProgressBar.setBackgroundResource(R.drawable.pb_custom_progress);//Color.parseColor("#55000000")
                padding = context.getResources().getDimensionPixelOffset(R.dimen.padding);
            } else {
                padding = context.getResources().getDimensionPixelOffset(R.dimen.padding);
                mProgressBar = new ProgressBar(context, null, Android.R.attr.progressBarStyleSmall);
            }
            mProgressBar.setPadding(padding, padding, padding, padding);
            mProgressBar.setBackgroundResource(R.drawable.pg_back);
            mProgressBar.setIndeterminate(true);
                try {
                    color__ = AppData.getTopColor(context);//UservaluesModel.getAppSettings().getSelectedColor();
                } catch (Exception e) {
                    color__ = "#FF4081";
                }
                int color = Color.parseColor(color__);
//                color=getContrastColor(color);
//                color__ = color__.replaceAll("#", "");//R.color.colorAccent
                mProgressBar.getIndeterminateDrawable().setColorFilter(color, Android.graphics.PorterDuff.Mode.SRC_ATOP);
            } 
            }

            RelativeLayout.LayoutParams params = new
                    RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            rl = new RelativeLayout(context);
            if (!isMiddle) {
                int valueInPixels = (int) context.getResources().getDimension(R.dimen.padding);
                lp.setMargins(0, 0, 0, (int) (valueInPixels / 1.5));//(int) Utils.convertDpToPixel(valueInPixels, context));
                rl.setClickable(false);
                lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            } else {
                rl.setGravity(Gravity.CENTER);
                rl.setClickable(true);
            }
            lp.addRule(RelativeLayout.CENTER_IN_PARENT);
            mProgressBar.setScaleY(1.55f);
            mProgressBar.setScaleX(1.55f);
            mProgressBar.setLayoutParams(lp);

            rl.addView(mProgressBar);
            layout.addView(rl, params);
        }
    }

    public void show() {
        if (mProgressBar != null)
            mProgressBar.setVisibility(View.VISIBLE);
    }

    public void hide() {
        if (mProgressBar != null) {
            rl.setClickable(false);
            mProgressBar.setVisibility(View.INVISIBLE);
        }
    }
}

Et puis appelez 

customProgressBar = new CustomProgressBar (Activity, true);
customProgressBar .show();
0
VV W