android - studio - Progreso redondeado dentro de la barra de progreso redondeada
proyectos android studio pdf (6)
¿Cómo logramos el ''recorte'' al comienzo con esta solución?
Lo que necesitas es limitar el valor de progreso mínimo, como:
final int minProgress = pb.getMax() * {20dp} / pb.getWidth();
progress = Math.max(minProgress, progress);
pb.setProgress(progress);
Use el código de arriba para postprocesar su valor de progreso está bien. No es un error extraíble, sino un efecto de estiramiento correcto.
Estoy tratando de crear una barra de progreso personalizada en una aplicación en la que estamos trabajando, y la última parte que necesito es el propio indicador de progreso. En su lugar, quiero que la barra esté redondeada al igual que los bordes izquierdo y derecho de la barra de progreso, como en la segunda imagen (menos el círculo rojo, por supuesto).
Aquí está la definición de diseño de la barra de progreso (el resto del archivo de diseño se omite por brevedad):
<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"
/>
y aquí está el archivo 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>
¿Cómo hago esto? No veo ninguna opción que me permita definir el indicador de progreso. ¿Debo estar haciendo esto de una manera diferente? Todavía soy bastante nuevo en Android, por lo que cualquier orientación es apreciada.
@Ando: su solución está muy cerca de lo que necesito. El inicio del movimiento del indicador es el problema ahora, y supongo que es porque no es un clip como el original. Cuando se enciende el indicador, y hasta cierto punto al principio, parece que está "apretado"
hasta que llegue al punto apropiado, entonces se ve bien:
¿Cómo logramos el ''recorte'' al comienzo con esta solución?
Para @bladefury, como puede ver, en comparación con el borde superior de la imagen de arriba, parece que se ha aplanado.
EDITAR: Después de no haber mirado esto durante bastante tiempo, miré un nuevo componente en https://github.com/akexorcist/Android-RoundCornerProgressBar/issues , y tiene el mismo problema que las sugerencias aquí.
Puede utilizar esta biblioteca para la barra de progreso de esquinas redondeadas
<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
Puedes usar seekbar para esto también
revisa mi publicación aquí: https://.com/a/41206481/6033946
Intente esto, puede hacer lo que quiera modificando el color, el ancho y la altura del pulgar y la barra de búsqueda en xml.
Una opción que quizás sea un poco más práctica es implementar una vista personalizada de la barra de progreso.
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);
}
}
Luego en su diseño:
<view.CustomProgressBar
android:layout_height="30dp"
android:layout_width="match_parent"
progressBarValue="66"/>
Lo que da el resultado:
simplemente cambia tu archivo progress_bar_states.xml: como en el siguiente ejemplo
<?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>
aquí custom_progress_primary.xml file: como abajo
<?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>
ProgressBar
usa ClipDrawable
, que se puede ClipDrawable
con un rectángulo. Por lo tanto, puede establecer un dibujable que recorte el rectángulo de la esquina a la barra de progreso, y aquí le indicamos cómo:
Primero, elimine la etiqueta <clip>
en su barra de progreso dibujable:
<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>
Luego, extienda la barra de progreso como esta:
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;
}
}
y aquí está RoundClipDrawable
, modificado desde ClipDrawable
: