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).
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é"
jusqu'à ce qu'il atteigne le point approprié, tout va bien:
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.
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.
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
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>
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:
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.
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
: