Barra de progreso redondeada en ambos lados en android

Estoy intentando crear una barra de progreso personalizada en android. He utilizado el siguiente archivo xml para ello (progress_bar_horizontal.xml):

<?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> <corners android:radius="8dip" /> <stroke android:width="2dip" android:color="#FFFF"/> <solid android:color="#FFFF"/> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="8dip" /> <stroke android:width="2dip" android:color="#FFFF"/> <solid android:color="#FF00"/> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="8dip" /> <stroke android:width="2dip" android:color="#FFFF"/> <solid android:color="#FF00"/> </shape> </clip> </item> </layer-list> 

Todo funciona muy bien, aparte del hecho de que me gustaría tener el progreso en mi barra de progreso redondeado en ambos lados. El citado código hace que una barra de progreso se redondee en el lado izquierdo y simplemente corte (no redondeado) en el lado derecho. Es debido a la etiqueta de clip probablemente. ¿Podrías ayudarme por eso? ¿Qué debo cambiar para tener el progreso en mi barra de progreso redondeado en ambos lados?

El diseño completo va a continuación:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/gradient_progress" android:padding="10dip" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/progress_header" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FF000000" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" android:text="Uploading" /> <TextView android:id="@+id/progress_percent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FF000000" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" android:text="55%" android:paddingLeft="10dip" /> </LinearLayout> <ProgressBar android:id="@+id/progress_bar" style="?android:attr/progressBarStyleHorizontal" android:layout_gravity="center" android:layout_width="fill_parent" android:layout_height="wrap_content" android:progressDrawable="@drawable/progress_bar_horizontal" android:maxHeight="12dip" android:minHeight="12dip" android:max="100" /> </LinearLayout> </LinearLayout> 

Aquí está el resultado de mi esfuerzo: link text

Me gustaría que la barra roja tenga bordes redondeados en el lado derecho también. Muchas gracias por sus comentarios.

He aquí una respuesta actualizada para los tiempos:

El código fuente de Android utiliza los archivos del Patch 9 para lograr el efecto: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/ Res / res / drawable / progress_horizontal_holo_dark.xml /

Así que empieza en tu diseño xml:

 <ProgressBar android:id="@+id/custom_progress_bar" style="@android:style/Widget.ProgressBar.Horizontal" android:indeterminateOnly="false" android:progressDrawable="@drawable/custom_progress_bar_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:minHeight="13" android:progress="33" android:secondaryProgress="66" /> 

Usted puede mover mucho de esto a un xml del estilo pero ése está al lado del punto. Lo que realmente nos interesa es android:progressDrawable="@drawable/custom_progress_bar_horizontal" – que nos va a permitir especificar nuestras propias barras de progreso personalizadas:

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background" android:drawable="@android:drawable/custom_progress_bg" /> <item android:id="@android:id/secondaryProgress"> <scale android:scaleWidth="100%" android:drawable="@android:drawable/custom_progress_secondary" /> </item> <item android:id="@android:id/progress"> <scale android:scaleWidth="100%" android:drawable="@android:drawable/custom_progress_primary" /> </item> </layer-list> 

O usted no tiene que utilizar un parche 9 para su fondo – por ejemplo aquí es un fondo blanco simple con una frontera 1dp:

 <item android:id="@android:id/background"> <shape> <corners android:radius="6.5dp" /> <solid android:color="@android:color/white" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape> </item> 

Android Asset Studio tiene una impresionante herramienta para ayudarte a generar archivos de Patch 9: http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html

Ejemplo primario xdpi png con relleno antes de la herramienta: Barra de progreso principal
Ejemplo secundario xdpi png con relleno antes de la herramienta: Barra de progreso secundaria

Y la salida final: Barra de progreso personalizada

Simplemente cambie la etiqueta <clip> a <scale> esta manera:

 <scale android:scaleWidth="100%"> 

Por lo que sé, esto no es posible. Debido a que internamente ClipDrawable (es decir, etiqueta de clip) corta la forma dada / canvas.clipRect() usando canvas.clipRect() . Por cierto, puede copiar la fuente ClipDrawable desde aquí y recortar una ruta determinada en función del nivel de progreso.

Para resolver el problema en el que los gráficos finales se solapan cuando el progreso es muy bajo, he escrito una extensión a la clase ProgressBar que agrega un desplazamiento inicial fijo a la barra de progreso, mientras que de otro modo funciona como normal.

Simplemente llame 'setMaxWithPercentOffset ()' o 'setMaxWithOffset ()' en lugar de 'setMax ()' pasando el valor que desea agregar como desplazamiento inicial a la barra de progreso.

Si alguien ha resuelto este problema sin requerir el inicio de compensación, házmelo saber!

 /** * This progress bar can be used when the progress bar end graphics are styled in some way. * In this case, the progress bar must always have a small percentage of progress, otherwise * the styled ends of the progress overlap each other. * */ public class EndStyledProgressBar extends ProgressBar { private static final int DEFAULT_START_OFFSET_PERCENT = 5; private int mStartOffset; private int mRealMax; public EndStyledProgressBar(Context context) { super(context); commonConstructor(); } public EndStyledProgressBar(Context context, AttributeSet attrs) { super(context, attrs); commonConstructor(); } public EndStyledProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); commonConstructor(); } private void commonConstructor() { mRealMax = super.getMax(); mStartOffset = 0; setMaxWithPercentOffset(DEFAULT_START_OFFSET_PERCENT, mRealMax); super.setProgress(super.getProgress() + mStartOffset); super.setSecondaryProgress(super.getSecondaryProgress() + mStartOffset); } public void setProgress(int progress) { super.setProgress(progress + mStartOffset); } public void setSecondaryProgress(int secondaryProgress) { super.setSecondaryProgress(secondaryProgress + mStartOffset); } public int getProgress() { int realProgress = super.getProgress(); return isIndeterminate() ? 0 : (realProgress - mStartOffset); } public int getSecondaryProgress() { int realSecondaryProgress = super.getSecondaryProgress(); return isIndeterminate() ? 0 : (realSecondaryProgress - mStartOffset); } public int getMax() { return mRealMax; } /** * Don't call this, instead call setMaxWithPercentOffset() or setStartOffsetInPercent() * * @param max */ public void setMax(int max) { super.setMax(max); } /** * Sets a new max with a start offset (in percent) included. * * @param startOffsetInPercent start offset for the progress bar to avoid graphic errors. */ public void setMaxWithPercentOffset(int startOffsetInPercent, int max) { mRealMax = max; int startOffset = (mRealMax * startOffsetInPercent) / 100; setMaxWithOffset(startOffset, max); } /** * Sets a new max with a start offset included. * * @param startOffset start offset for the progress bar to avoid graphic errors. */ public void setMaxWithOffset(int startOffset, int max) { mRealMax = max; super.setMax(startOffset + max); setStartOffset(startOffset); super.setMax(startOffset + max); } /** * Sets a new start offset different from the default of 5% * * @param startOffset start offset for the progress bar to avoid graphic errors. */ private void setStartOffset(int startOffset) { int newStartOffset = startOffset; // Ensure the start offset is not outside the range of the progress bar if (newStartOffset < 0) newStartOffset = 0; if (newStartOffset >= super.getMax()) newStartOffset = super.getMax(); // Apply the start offset difference if (mStartOffset != newStartOffset) { int diff = newStartOffset - mStartOffset; super.setMax(super.getMax() + diff); super.setProgress(super.getProgress() + diff); super.setSecondaryProgress(super.getSecondaryProgress() + diff); mStartOffset = newStartOffset; } } } 

Final redondeado ambos lados de la barra de progreso sin 9-patch es: android:progressDrawable="@drawable/progress_horizontal_green"

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/progress"> <scale android:scaleWidth="100%"> <shape> <corners android:radius="5dip"/> <solid android:color="#33FF33"/> </shape> </scale> </item> 

  • Cómo configurar windowDrawsSystemBarBackgrounds de forma programática?
  • Implementar una transición de elementos compartidos con AngularJS
  • Imprimir la pila trasera actual en el registro
  • Latch (usado para esperar la respuesta asíncrona) congela el WebView (y la interfaz de usuario)
  • Anulación de onTouchEvent que compite con ScrollView
  • Ajuste del tamaño de los botones en porcentaje
  • ¿Cómo puedo mejorar la apariencia de una aplicación para Android?
  • ¿Cómo puedo permitir que un usuario reordene los elementos en una lista?
  • El relleno no afecta a <shape> en un diseño XML
  • Actualizar la interfaz de usuario desde el subproceso
  • IU distorsionada con Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.