web-dev-qa-db-fra.com

Progression arrondie dans la barre de progression arrondie

J'essaie de créer une barre de progression personnalisée dans une application sur laquelle nous travaillons. Le dernier élément dont j'ai besoin est l'indicateur de progression lui-même. Au lieu de cela, je souhaite que cette barre soit arrondie, tout comme les bords gauche et droit de la barre de progression elle-même, comme dans la deuxième image (sans le cercle rouge bien sûr).

enter image description here

enter image description here

Voici la définition de la mise en page de la barre de progression (le reste du fichier de mise en page est omis pour des raisons de brièveté):

<ProgressBar
    Android:id="@+id/progress_bar"
    Android:layout_width="fill_parent"
    Android:layout_height="60dp"
    Android:padding="3dp"
    Android:max="100"
    Android:progressDrawable="@drawable/progress_bar_states"
    Android:layout_marginTop="10dp"
    style="?android:attr/progressBarStyleHorizontal"
    Android:indeterminateOnly="false"
    Android:layout_below="@id/textview2"
    Android:layout_alignLeft="@id/textview2"
    />

et voici le fichier progress_bar_states.xml:

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

    <item Android:id="@Android:id/background">
        <shape>
            <solid Android:color="#20ffff00"/>
            <corners Android:radius="60dp"/>
        </shape>
    </item>

    <item Android:id="@Android:id/progress">
        <clip>
            <shape>
                <solid Android:color="#20ffffff"/>
                <corners Android:radius="60dp"/>
            </shape>
        </clip>
    </item>

</layer-list>

Comment puis-je faire cela? Je ne vois aucune option pour me permettre de définir l'indicateur de progression du tout. Devrais-je faire cela d'une manière différente? Je suis encore assez nouveau sur Android, donc toute orientation est appréciée.

@Ando - votre solution est very proche de ce dont j'ai besoin. Le début du mouvement de l'indicateur est le problème maintenant, et je suppose que c'est parce que ce n'est pas un clip comme l'original. Lorsque l’indicateur se met en marche et jusqu’à un certain point au début, on dirait qu’il est "pressé" 

enter image description here

jusqu'à ce qu'il atteigne le point approprié, tout va bien:

enter image description here

Comment pouvons-nous accomplir le «découpage» au début avec cette solution?

Pour @bladefury - comme vous pouvez le constater, par rapport au bord supérieur de l’image ci-dessus, elle semble être aplatie.

enter image description here

EDIT: Après ne pas avoir regardé cela assez longtemps, j’ai regardé un nouveau composant à https://github.com/akexorcist/Android-RoundCornerProgressBar/issues , et a le même problème que les suggestions présentées ici.

17
TheIcemanCometh

Vous pouvez utiliser cette bibliothèque pour la barre de progression des coins arrondis

<com.akexorcist.roundcornerprogressbar.RoundCornerProgressBar
        Android:layout_width="dimension"
        Android:layout_height="dimension"
        app:rcProgress="float"
        app:rcSecondaryProgress="float"
        app:rcMax="float"
        app:rcRadius="dimension"
        app:rcBackgroundPadding="dimension"
        app:rcReverse="boolean"
        app:rcProgressColor="color"
        app:rcSecondaryProgressColor="color"
        app:rcBackgroundColor="color" />

Gradle

compile 'com.akexorcist:RoundCornerProgressBar:2.0.3'

https://github.com/akexorcist/Android-RoundCornerProgressBar

0

il suffit de changer votre fichier progress_bar_states.xml: comme ci-dessous 

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >

<item Android:id="@Android:id/background">
    <shape>
        <solid Android:color="#20ffff00" />

        <corners Android:radius="20dp" />
    </shape>
</item>
<item Android:id="@Android:id/progress">

    <!-- <clip> -->
    <!-- <shape> -->
    <!-- <solid Android:color="@Android:color/black" /> -->


    <!-- <corners -->
    <!-- Android:bottomRightRadius="30dp" -->
    <!-- Android:radius="60dp" -->
    <!-- Android:topRightRadius="30dp" /> -->
    <!-- </shape> -->
    <!-- </clip> -->

    <scale
        Android:drawable="@drawable/custom_progress_primary"
        Android:scaleWidth="98%" /><!-- change here -->
</item>

ici fichier custom_progress_primary.xml: comme ci-dessous 

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >

<corners
    Android:radius="20dp"
    Android:topLeftRadius="20dp"
    Android:topRightRadius="20dp" />

<solid Android:color="@Android:color/white" />

<stroke
    Android:width="1dp"
    Android:color="@Android:color/darker_gray" />

</shape>
26
Ando Masahashi

Une option peut-être un peu plus pratique consiste à implémenter une vue de barre de progression personnalisée.

public class CustomProgressBar extends View
{
    // % value of the progressbar.
    int progressBarValue = 0;

    public CustomProgressBar(Context context)
    {
        super(context);
    }

    public CustomProgressBar(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        progressBarValue = attrs.getAttributeIntValue(null, "progressBarValue", 0);
    }

    public void setValue(int value)
    {
        progressBarValue = value;
        invalidate();
    }

    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        float cornerRadius = 30.0f;

        // Draw the background of the bar.
        Paint backgroundPaint = new Paint();
        backgroundPaint.setColor(Color.LTGRAY);
        backgroundPaint.setStyle(Paint.Style.FILL);
        backgroundPaint.setAntiAlias(true);

        RectF backgroundRect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
        canvas.drawRoundRect(backgroundRect, cornerRadius, cornerRadius, backgroundPaint);

        // Draw the progress bar.
        Paint barPaint = new Paint();
        barPaint.setColor(Color.GREEN);
        barPaint.setStyle(Paint.Style.FILL);
        barPaint.setAntiAlias(true);

        float progress = (backgroundRect.width() / 100) * progressBarValue;
        RectF barRect = new RectF(0, 0, progress, canvas.getClipBounds().bottom);

        canvas.drawRoundRect(barRect, cornerRadius, cornerRadius, barPaint);

        // Draw progress text in the middle.
        Paint textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(34);

        String text = progressBarValue + "%";
        Rect textBounds = new Rect();

        textPaint.getTextBounds(text, 0, text.length(), textBounds);

        canvas.drawText(text,
                backgroundRect.centerX() - (textBounds.width() / 2),
                backgroundRect.centerY() + (textBounds.height() / 2),
                textPaint);

    }
}

Puis dans votre mise en page:

<view.CustomProgressBar
    Android:layout_height="30dp"
    Android:layout_width="match_parent"
    progressBarValue="66"/>

Ce qui donne le résultat:

 Custom progress bar result

4
jverrijt

vous pouvez aussi utiliser seekbar

vérifier mon post ici: https://stackoverflow.com/a/41206481/6033946

Essayez ceci, vous pourrez peut-être faire ce que vous voulez en modifiant la couleur, la largeur et la hauteur du pouce et de la barre de recherche en XML.

0
tahaDev

ProgressBar utilise ClipDrawable, clips clipsables avec un rectangle. Ainsi, vous pouvez définir une barre de progression sur le rectangle d'angle arrondi que vous pouvez dessiner, et voici comment:

tout d’abord, supprimez la balise <clip> dans votre barre de progression

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

<item Android:id="@Android:id/background">
    <shape>
        <solid Android:color="#20ffff00"/>
        <corners Android:radius="60dp"/>
    </shape>
</item>

<item Android:id="@Android:id/progress">
        <shape>
            <solid Android:color="#20ffffff"/>
            <corners Android:radius="60dp"/>
        </shape>
</item>

ensuite, étendez la barre de progression comme ceci:

public class RoundIndicatorProgressBar extends ProgressBar {

    private static final float CORNER_RADIUS_DP = 60.0f;

    public RoundIndicatorProgressBar(Context context) {
        this(context, null);
    }

    public RoundIndicatorProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundIndicatorProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    @Override
    public void setProgressDrawable(Drawable d) {
        super.setProgressDrawable(tileify(d, false));
    }

    private Drawable tileify(Drawable drawable, boolean clip) {
        if (drawable instanceof LayerDrawable) {
            LayerDrawable background = (LayerDrawable) drawable;
            final int N = background.getNumberOfLayers();
            Drawable[] outDrawables = new Drawable[N];

            for (int i = 0; i < N; i++) {
                int id = background.getId(i);
                outDrawables[i] = tileify(background.getDrawable(i),
                        (id == Android.R.id.progress || id == Android.R.id.secondaryProgress));
            }

            LayerDrawable newBg = new LayerDrawable(outDrawables);

            for (int i = 0; i < N; i++) {
                newBg.setId(i, background.getId(i));
            }

            return newBg;

        } else {
            if (clip) {
                return new RoundClipDrawable(drawable, dp2px(getContext(), CORNER_RADIUS_DP));
            }
        }
        return drawable;
    }
    public static float dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return dp * scale;
    }

}

et voici RoundClipDrawable, modifié de ClipDrawable:

RoundClipDrawable.Java Gist

0
bladefury