Por padrão, o ProgressBar tem um certo preenchimento acima e abaixo da própria barra. Existe uma maneira de remover esse preenchimento para ter apenas a barra no final?
android:minHeight="4dp"
Por padrão, o ProgressBar tem um certo preenchimento acima e abaixo da própria barra. Existe uma maneira de remover esse preenchimento para ter apenas a barra no final?
android:minHeight="4dp"
Respostas:
Eu uso o seguinte como uma solução alternativa para esse problema.
android:layout_marginBottom="-8dp"
android:layout_marginTop="-4dp"
android:layout_marginTop="-6dp"
trabalhou para mim. Gostaria de saber se é dependente do dispositivo? Eu só testei no Xperia Z1
Framelayout
(como em esta resposta é melhor solução e não depende do tamanho do telefone / tipo de versão / os
Foi assim que usei a resposta de Juozas:
altura do meu ProgressBar
é 4dp. Então eu criei um FrameLayout
com altura 4dp e defina o layout_gravity
de ProgressBar
como center
. Funciona como um 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>
Acabei usando uma biblioteca personalizada para resolver esse problema. A maioria das outras soluções funciona, mas os resultados não são consistentes em vários dispositivos.
MaterialProgressBar
- Aparência consistente no Android 4.0 ou superior.
- Tonalidade correta nas plataformas.
- Capaz de remover o preenchimento intrínseco da estrutura ProgressBar.
- Capaz de ocultar a faixa da estrutura ProgressBar horizontal.
- Usado como um substituto para o framework ProgressBar.
Para adicionar como uma dependência gradle:
compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'
Para adicionar uma ProgressBar sem preenchimento intrínseco ao seu 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"
faz o truque. Para mais detalhes, consulte a página do GitHub .
Se alguém ainda precisar de ajuda, tente o seguinte:
<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" />
Aqui, a barra de progresso está dentro do ConstraintLayout , e os constraintTop_toTopOf e constraintBottom_toTopOf atributos devem ser aplicados ao mesmo elemento (neste caso, é diretriz).
É possível desenhar ProgressBar verticalmente centralizado dentro de um pai que cortaria o preenchimento. Como o ProgressBar não pode se desenhar maior que o pai, precisamos criar um pai grande para colocar dentro de uma exibição 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>
Para remover o preenchimento vertical ProgressBar
, você pode fazer isso
ProgressBar
O exemplo contém 1 wrap_content ProgressBar
, 1 8dp ProgressBar
, 1 100dpProgressBar
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
...
android:layout_height="8dp"
android:scaleY="2" />
Uma solução completa para esse problema seria a seguinte. Caso alguém precise de fragmentos de código, foi isso que eu fiz.
Aqui está o arquivo 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 para o meu arquivo de estilos local.
<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>
E, finalmente, defina a altura mínima como 4dp no meu arquivo de layout 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" />
<your-sdk-folder>/platforms/android-17/data/res/drawable-hdpi/
Encontrei o mesmo problema ao usar a barra de progresso com o estilo horizontal.
A causa principal é que o drawable padrão de 9 correções para a barra de progresso: (progress_bg_holo_dark.9.png) possui alguns pixels verticais transparentes como preenchimento.
A solução final que funcionou para mim: personalizar o progresso desenhável, meu código de exemplo da seguinte forma:
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 de 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"/>
Um truque é adicionar margens negativas à sua barra de progresso.
Abaixo está um exemplo do código XML, supondo que ele esteja na parte superior da tela:
<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" />
A resposta de Subin parece ser a única (atualmente) que não é um hack frágil sujeito a falhas em versões futuras do Android ProgressBar.
Mas, em vez de ter o trabalho de dividir os recursos, modificá-los e mantê-los indefinidamente, optei por usar a biblioteca MaterialProgressBar , que faz isso por nós:
<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"
/>
No build.gradle:
// Android horizontal ProgressBar doesn't allow removal of top/bottom padding
compile 'me.zhanghai.android.materialprogressbar:library:1.1.6'
Esse projeto tem uma boa demonstração que mostra as diferenças entre ele e o ProgressBar interno.
se alguém ainda estiver procurando uma solução - verifique este comentário
defina a altura mínima para 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" />
Eu uso minHeight e maxHeigh. Ajuda para diferentes versões da 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" />
Ele precisa usar os dois. A API 23 funciona bem com
android:layout_height="wrap_content"
android:minHeight="0dp"
Porém, versões mais baixas da API aumentam a altura da barra de progresso para maxHeight nesse caso.
Tente o seguinte:
<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, em seguida, configure a barra de progresso de acordo com as suas necessidades, pois ela exibirá inicialmente uma barra de tamanho médio com uma tonalidade de progresso amarela e uma tonalidade de fundo cinza de progresso. Além disso, observe que não há preenchimento vertical.
Use assim, dentro do 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>
adicionar o android: progressDrawable a uma lista de camadas definida no drawable corrigiu o problema para mim. Ele funciona mascarando a barra de progresso em um drawable personalizado
exemplo de implementação descrito em https://stackoverflow.com/a/4454450/1145905
Estou usando style="@style/Widget.AppCompat.ProgressBar.Horizontal"
e foi bastante fácil se livrar das margens. Esse estilo é:
<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>
Acabei de substituir a 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" />
Não é necessário baixar nenhum novo módulo ou até mesmo colocar um FrameLayout na barra de progresso. Estes são todos apenas hacks. Apenas 2 etapas:
No seu Whatever.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, altere os valores como desejar.
Não gosta dos cantos arredondados?
Remover raio do canto
Não gosta das cores? Mude as cores, etc. Feito!
<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>
Geralmente, estas são as etapas para alterar o código de qualquer coisa que você não gosta. Basta encontrar o código fonte e descobrir o que mudar. Se você seguir o código-fonte ProgressBar, encontrará um arquivo chamado progress_horizontal.xml que ele faz referência. Basicamente, como eu resolvo todos os meus problemas de 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 usar o Material ProgressIndicator que não possui margem oculta.
<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" />
Uma solução simples não-truques que é compatível com qualquer versão do Android e não precisa de bibliotecas externas está fingindo ProgressBar
com dois Views
interiorLinearLayout
. Foi assim que acabei. Parece bastante elegante e essa abordagem é bastante flexível - você pode animar de maneiras divertidas, adicionar texto etc.
Layout:
<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 (com alguma elevação adicionada):
A melhor solução deve ser
android:minHeight="0dp"
Nenhuma solução alternativa e funciona como um encanto.
minHeight
tamanho maior que 0 (digamos, 32dp talvez) predefinido. Ao alterar essa propriedade, você obtém uma aparência diferente.
maxHeight
não funciona.