android - programacion - Eliminar el relleno vertical del ProgressBar horizontal
progressbar android (13)
Por defecto, ProgressBar tiene un cierto relleno encima y debajo de la barra. ¿Hay alguna manera de eliminar este relleno para que solo tenga la barra al final?
Así es como utilicé la respuesta de Juozas:
La altura de mi ProgressBar
es 4dp. Así que creé un FrameLayout
con altura 4dp y establecí el layout_gravity
de ProgressBar
en el center
. Funciona como un encanto.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
Es posible dibujar ProgressBar verticalmente centrado dentro de un elemento primario que recortaría el relleno. Como ProgressBar no puede dibujarse más grande que el elemento principal, debemos crear un elemento principal grande para colocar dentro de una vista de recorte.
<FrameLayout
android:id="@+id/clippedProgressBar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="4dp"
tools:ignore="UselessParent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_gravity="center_vertical">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true"/>
</FrameLayout>
</FrameLayout>
Estoy usando style="@style/Widget.AppCompat.ProgressBar.Horizontal"
y fue bastante fácil deshacerse de los márgenes. Ese estilo es:
<item name="progressDrawable">@drawable/progress_horizontal_material</item>
<item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
Simplemente eliminé la altura mínima / máxima:
<ProgressBar
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="2dp"
android:indeterminate="true"
android:minHeight="2dp"
android:maxHeight="2dp" />
La respuesta de Subin parece ser la única (actualmente) que no es un truco frágil sujeto a rotura en versiones futuras de Android ProgressBar.
Pero en lugar de tomarse el trabajo de liberar los recursos, modificarlos y mantenerlos indefinidamente, he optado por utilizar la biblioteca MaterialProgressBar , que hace eso por nosotros:
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="bottom"
custom:mpb_progressStyle="horizontal"
custom:mpb_showTrack="false"
custom:mpb_useIntrinsicPadding="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
/>
En build.gradle:
// Android horizontal ProgressBar doesn''t allow removal of top/bottom padding
compile ''me.zhanghai.android.materialprogressbar:library:1.1.6''
Ese proyecto tiene una buena demostración que muestra las diferencias entre él y el ProgressBar incorporado.
Me encontré con el mismo problema al usar la barra de progreso con estilo Horizontal.
La causa principal es que el parche predeterminado de 9 parches para la barra de progreso: (progress_bg_holo_dark.9.png) tiene algunos píxeles transparentes verticales como relleno.
La solución final que funcionó para mí: personalizar el progreso dibujable, mi código de muestra de la siguiente manera:
custom_horizontal_progressbar_drawable.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 android:shape="rectangle">
<solid android:color="#33ffffff" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape android:shape="rectangle">
<solid android:color="#ff9800" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape android:shape="rectangle">
<solid android:color="#E91E63" />
</shape>
</clip>
</item>
</layer-list>
fragmento de diseño:
<ProgressBar
android:id="@+id/song_progress_normal"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_alignParentBottom="true"
android:progressDrawable="@drawable/custom_horizontal_progressbar_drawable"
android:progress="0"/>
Pruebe lo siguiente:
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:progress="25"
android:progressTint="@color/colorWhite"
android:progressBackgroundTint="@color/colorPrimaryLight"
android:layout_width="match_parent"
android:layout_height="4dp" />
... y luego configure la barra de progreso según sus necesidades, ya que inicialmente mostrará una barra de tamaño medio con un tinte de progreso de color amarillo con un tono de fondo de progreso grisáceo. Además, observe que no hay relleno vertical.
Solo prueba debajo de las líneas de código en tu diseño XML.
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-7dp"
android:layout_marginBottom="-7dp"
android:indeterminate="true" />
Terminé usando una biblioteca personalizada para resolver este problema. La mayoría de las otras soluciones funcionan, pero los resultados no son consistentes en varios dispositivos.
MaterialProgressBar
- Apariencia consistente en Android 4.0+.
- Corregir el tinte en las plataformas
- Capaz de eliminar el relleno intrínseco del marco ProgressBar.
- Capaz de ocultar la pista del marco horizontal ProgressBar.
- Se usa como un reemplazo directo para el marco ProgressBar.
Para agregar como una dependencia de Gradle:
compile ''me.zhanghai.android.materialprogressbar:library:1.1.7''
Para agregar una ProgressBar sin ningún relleno intrínseco a su diseño:
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:layout_width="wrap_content"
android:layout_height="4dp"
android:indeterminate="true"
app:mpb_progressStyle="horizontal"
app:mpb_useIntrinsicPadding="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal" />
app:mpb_useIntrinsicPadding="false"
hace el truco. Para obtener más detalles, consulte la página de GitHub .
Una solución completa a este problema sería la siguiente. Por si acaso, si alguien necesita fragmentos de código, esto es lo que hice.
- Copió los 8 esquemas de barra de progreso horizontales indeterminados
- Editó los dibujables utilizando un manipulador de imágenes y elimina los rellenos innecesarios
- Copió el XML dibujable llamado progress_indeterminate_horizontal_holo.xml de la plataforma de Android
- Copió el estilo Widget.ProgressBar.Horizontal y sus padres
- Establecer el estilo y min_height manualmente en el diseño
Aquí está el progress_indeterminate_horizontal_holo.xml
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/progressbar_indeterminate_holo1" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo2" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo3" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo4" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo5" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo6" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo7" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo8" android:duration="50" />
Recursos de estilo copiados en mi archivo de estilos locales.
<style name="Widget">
<item name="android:textAppearance">@android:attr/textAppearance</item>
</style>
<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
</style>
<style name="Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
</style>
Y finalmente, establezca la altura mínima en 4dp en mi archivo de diseño local.
<ProgressBar
android:id="@+id/pb_loading"
style="@style/Widget.ProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminate="true"
android:minHeight="4dp"
android:minWidth="48dp"
android:progressDrawable="@drawable/progress_indeterminate_horizontal_holo" />
Una solución simple sin trucos que es compatible con cualquier versión de Android y no necesita bibliotecas externas está falsificando ProgressBar
con dos Views
dentro de LinearLayout
. Esto es con lo que terminé. Se ve bastante ordenado y este enfoque es bastante flexible: puedes animarlo de maneras funky, agregar texto, etc.
Diseño:
<LinearLayout
android:id="@+id/inventory_progress_layout"
android:layout_width="match_parent"
android:layout_height="4dp"
android:orientation="horizontal">
<TextView
android:id="@+id/inventory_progress_value"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/inventory_progress_remaining"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Código:
public void setProgressValue(float percentage) {
TextView progressValue = (TextView) findViewById(R.id.inventory_progress_value);
TextView progressRemaining = (TextView) findViewById(R.id.inventory_progress_remaining);
LinearLayout.LayoutParams paramsValue = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams paramsRemaining = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
paramsValue.weight = (100 - percentage);
paramsRemaining.weight = percentage;
progressValue.setLayoutParams(paramsValue);
progressRemaining.setLayoutParams(paramsRemaining);
}
Resultado (con alguna elevación agregada):
Utilizo lo siguiente como una solución para este problema.
android:layout_marginBottom="-8dp"
android:layout_marginTop="-4dp"
Yo uso minHeight y maxHeigh. Ayuda para diferentes versiones de Api.
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="3dp"
android:minHeight="3dp" />
Necesita usar ambos. Api 23 funciona bien con
android:layout_height="wrap_content"
android:minHeight="0dp"
Pero las versiones de Api inferiores aumentan la altura de la barra de progreso a maxHeight en ese caso.
agregando el android: progressDrawable a una lista de capas definida en drawable solucionó el problema para mí. Funciona enmascarando la barra de progreso en un dibujo personalizable
Implementación de ejemplo descrita en https://.com/a/4454450/1145905