Per impostazione predefinita, la ProgressBar ha un certo riempimento sopra e sotto la barra stessa. C'è un modo per rimuovere questa imbottitura in modo da avere solo la barra alla fine?
android:minHeight="4dp"
Per impostazione predefinita, la ProgressBar ha un certo riempimento sopra e sotto la barra stessa. C'è un modo per rimuovere questa imbottitura in modo da avere solo la barra alla fine?
android:minHeight="4dp"
Risposte:
Uso quanto segue come soluzione alternativa per questo problema.
android:layout_marginBottom="-8dp"
android:layout_marginTop="-4dp"
android:layout_marginTop="-6dp"
ha funzionato per me. Mi chiedo se dipende dal dispositivo? Ho provato solo su Xperia Z1
Framelayout
(come in questa risposta è una soluzione migliore e non dipende dalle dimensioni del telefono / tipo / versione del sistema
Ecco come ho usato la risposta di Juozas:
l'altezza del mio ProgressBar
è 4dp. Quindi ho creato un FrameLayout
con altezza 4dp e ho impostato il layout_gravity
di ProgressBar
su center
. Funziona come un incantesimo.
<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>
Ho finito per utilizzare una libreria personalizzata per risolvere questo problema. La maggior parte delle altre soluzioni funziona ma i risultati non sono coerenti su vari dispositivi.
MaterialProgressBar
- Aspetto coerente su Android 4.0+.
- Correggere la colorazione sulle piattaforme.
- In grado di rimuovere il riempimento intrinseco del framework ProgressBar.
- Capace di nascondere la traccia del quadro ProgressBar orizzontale.
- Usato come sostituto immediato del framework ProgressBar.
Per aggiungere come dipendenza gradle:
compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'
Per aggiungere una ProgressBar senza riempimento intrinseco al layout:
<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"
fa il trucco. Per maggiori dettagli vedere la pagina GitHub .
Se qualcuno ha ancora bisogno di aiuto può provare questo:
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline"
android:indeterminate="true"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/guideline" />
Qui, la barra di avanzamento è all'interno di ConstraintLayout e gli attributi constraintTop_toTopOf e constraintBottom_toTopOf devono essere applicati allo stesso elemento (in questo caso, è la linea guida).
*** SOLUZIONE COMPLETA: ***
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="48dp">
<View
android:id="@+id/guideline"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
È possibile disegnare ProgressBar centrato verticalmente all'interno di un genitore che taglierebbe via il riempimento. Poiché ProgressBar non può disegnare se stesso più grande del genitore, dobbiamo creare un genitore grande da posizionare all'interno di una vista di ritaglio.
<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>
Per rimuovere l'imbottitura verticale di ProgressBar
, puoi farlo
ProgressBar
L'esempio contiene 1 wrap_content ProgressBar
, 1 8dp ProgressBar
, 1 100dpProgressBar
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
...
android:layout_height="8dp"
android:scaleY="2" />
Una soluzione completa a questo problema sarebbe la seguente. Nel caso in cui qualcuno avesse bisogno di frammenti di codice, questo è quello che ho fatto.
Ecco il 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" />
Risorse di stile copiate nel mio file di stili locale.
<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>
Infine, imposta l'altezza minima su 4dp nel mio file di layout locale.
<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" />
<your-sdk-folder>/platforms/android-17/data/res/drawable-hdpi/
Ho incontrato lo stesso problema durante l'utilizzo della barra di avanzamento con lo stile orizzontale.
La causa principale è che il disegno predefinito di 9 patch per la barra di avanzamento: (progress_bg_holo_dark.9.png) ha alcuni pixel trasparenti verticali come riempimento.
La soluzione finale che ha funzionato per me: personalizza i progressi disegnabili, il mio codice di esempio come segue:
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>
snippet di layout:
<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"/>
Un trucco è aggiungere margini negativi alla barra di avanzamento.
Di seguito è riportato un esempio del codice XML, assumendo che sia nella parte superiore dello schermo:
<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" />
La risposta di Subin sembra essere l'unica (attualmente) che non è un fragile hack soggetto a rotture nelle versioni future di Android ProgressBar.
Ma piuttosto che passare attraverso il problema di rompere le risorse, modificarle e mantenerle a tempo indeterminato, ho scelto di utilizzare la libreria MaterialProgressBar , che fa questo per noi:
<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"
/>
In build.gradle:
// Android horizontal ProgressBar doesn't allow removal of top/bottom padding
compile 'me.zhanghai.android.materialprogressbar:library:1.1.6'
Quel progetto ha una bella demo che mostra le differenze tra esso e la ProgressBar incorporata.
se qualcuno sta ancora cercando una soluzione, controlla questo commento
impostare l'altezza minima a 4 dp
android:minHeight="4dp"
-
<ProgressBar
android:id="@+id/web_view_progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="100"
android:min="0"
android:progress="5"
android:minHeight="4dp"
android:progressTint="@color/vodafone_red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:progress="60" />
Uso minHeight e maxHeigh. Aiuta per diverse versioni di 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" />
Deve utilizzare entrambi. Api 23 funziona bene con
android:layout_height="wrap_content"
android:minHeight="0dp"
Ma le versioni inferiori di Api aumentano l'altezza della barra di avanzamento a maxHeight in questo caso.
Prova quanto segue:
<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" />
... e quindi configurare la barra di avanzamento in base alle proprie esigenze poiché inizialmente visualizzerà una barra di medie dimensioni con una tinta di avanzamento di colore giallo con una tinta di sfondo di avanzamento grigiastro. Inoltre, nota che non c'è imbottitura verticale.
Usa in questo modo, all'interno di Linearlayout
<LinearLayout
android:layout_width="match_parent"
android:background="#efefef"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
android:layout_marginTop="-7dp"
android:layout_marginBottom="-7dp"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
/>
</LinearLayout>
l'aggiunta di android: progressDrawable a un elenco di livelli definito in drawable ha risolto il problema per me. Funziona mascherando la barra di avanzamento in un disegnabile personalizzato
esempio di implementazione descritta su https://stackoverflow.com/a/4454450/1145905
Sto usando style="@style/Widget.AppCompat.ProgressBar.Horizontal"
ed è stato abbastanza facile sbarazzarsi dei margini. Quello stile è:
<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>
Ho appena sovrascritto l'altezza min / max:
<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" />
Non è necessario scaricare alcun nuovo modulo o persino inserire un FrameLayout attorno alla barra di avanzamento. Questi sono solo hack. Solo 2 passaggi:
Nel tuo any.xml
<ProgressBar
android:id="@+id/workoutSessionGlobalProgress"
android:layout_width="match_parent"
android:layout_height="YOUR_HEIGHT"
android:progressDrawable="@drawable/progress_horizontal"
android:progress="0"
<!-- High value to make ValueAnimator smoother -->
android:max="DURATION * 1000"
android:indeterminate="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"/>
progress_horizontal.xml, modifica i valori come preferisci.
Non ti piacciono gli angoli arrotondati?
Rimuovi il raggio dell'angolo
Non ti piacciono i colori? Cambia i colori, ecc. Fatto!
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>
</layer-list>
In generale, questi sono i passaggi per modificare il codice di tutto ciò che non ti piace. Basta trovare il codice sorgente e capire cosa cambiare. Se segui il codice sorgente di ProgressBar, troverai un file chiamato progress_horizontal.xml a cui fa riferimento. Fondamentalmente come risolvo tutti i miei problemi XML.
<ProgressBar
android:layout_marginTop="-8dp"
android:layout_marginLeft="-8dp"
android:layout_marginRight="-8dp"
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:indeterminate="false"
android:indeterminateTint="@color/white"
android:max="100"
android:paddingStart="8dp"
android:paddingRight="0dp"
android:progressDrawable="@drawable/progress_bg" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:paddingTop="2dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
Basta usare Material ProgressIndicator che non ha margini nascosti.
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/progressBar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:indicatorColor="@color/colorPrimary"
app:trackColor="@color/colorAccent" />
Una semplice soluzione senza trucchi compatibile con qualsiasi versione di Android e che non necessita di librerie esterne è fingere ProgressBar
con due Views
all'interno LinearLayout
. Questo è ciò con cui sono finito. Sembra abbastanza pulito e questo approccio è abbastanza flessibile: puoi animarlo in modi stravaganti, aggiungere testo ecc.
Disposizione:
<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>
Codice:
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);
}
Risultato (con l'aggiunta di qualche elevazione):
La soluzione migliore dovrebbe essere
android:minHeight="0dp"
Nessuna soluzione alternativa e funziona come un fascino.
minHeight
valore predefinito maggiore di 0 (diciamo 32dp forse). Modificando questa proprietà si ottiene un aspetto diverso.
maxHeight
non funziona.