По умолчанию ProgressBar имеет определенные отступы над и под самой полосой. Есть ли способ удалить эту прокладку, чтобы полоса оставалась только в конце?
android:minHeight="4dp"
По умолчанию ProgressBar имеет определенные отступы над и под самой полосой. Есть ли способ удалить эту прокладку, чтобы полоса оставалась только в конце?
android:minHeight="4dp"
Ответы:
Я использую следующее решение этой проблемы.
android:layout_marginBottom="-8dp"
android:layout_marginTop="-4dp"
android:layout_marginTop="-6dp"
работал у меня. Интересно, зависит ли это от устройства? Я тестировал только Xperia Z1
Framelayout
(как в этом ответе - лучшее решение и не зависит от размера / типа / версии телефона /
Вот как я использовал ответ Юозаса:
высота у меня ProgressBar
4dp. Таким образом , я создал FrameLayout
с высотой 4ДПОМ и установите layout_gravity
из ProgressBar
в center
. Это работает как шарм.
<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>
В итоге я решил использовать специальную библиотеку для решения этой проблемы. Большинство других решений работают, но результаты неодинаковы на разных устройствах.
MaterialProgressBar
- Единый внешний вид на Android 4.0+.
- Правильная тонировка платформ.
- Возможность удалить внутреннее заполнение фреймворка ProgressBar.
- Возможность скрыть дорожку каркаса горизонтальной ProgressBar.
- Используется как замена для фреймворка ProgressBar.
Чтобы добавить как зависимость Gradle:
compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'
Чтобы добавить в макет ProgressBar без внутреннего отступа:
<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"
делает свое дело. Дополнительные сведения см. На странице GitHub .
Если кому-то все еще нужна помощь, попробуйте следующее:
<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" />
Здесь индикатор выполнения находится внутри ConstraintLayout , а атрибуты constraintTop_toTopOf и constraintBottom_toTopOf должны быть применены к одному и тому же элементу (в данном случае это рекомендация).
*** ПОЛНОЕ РЕШЕНИЕ: ***
<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>
Можно нарисовать вертикально центрированный ProgressBar внутри родительского элемента, который будет вырезать отступы. Поскольку ProgressBar не может рисовать больше, чем родительский, мы должны создать большой родительский элемент, который будет помещен в представление отсечения.
<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>
Чтобы удалить вертикальное заполнение ProgressBar
, вы можете сделать
ProgressBar
Пример содержит 1 wrap_content ProgressBar
, 1 8dp ProgressBar
, 1 100dpProgressBar
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
...
android:layout_height="8dp"
android:scaleY="2" />
Полное решение этой проблемы было бы следующим. На всякий случай, если кому-то понадобятся фрагменты кода, я так и сделал.
Вот прогресс_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" />
Ресурсы стилей скопированы в мой локальный файл стилей.
<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>
И, наконец, установите минимальную высоту на 4dp в моем локальном файле макета.
<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/
Я столкнулся с той же проблемой при использовании индикатора выполнения в горизонтальном стиле.
Основная причина заключается в том, что 9-патч по умолчанию, отображаемый для индикатора выполнения: (progress_bg_holo_dark.9.png), имеет несколько вертикальных прозрачных пикселей в качестве заполнения.
Окончательное решение, которое сработало для меня: настроить отображение прогресса, мой пример кода следующим образом:
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>
фрагмент макета:
<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"/>
Один из приемов - добавить отрицательные поля к индикатору выполнения.
Ниже приведен пример кода 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" />
Ответ Субина, кажется, единственный (в настоящее время), который не является хрупким взломом, который может сломаться в будущих выпусках Android ProgressBar.
Но вместо того, чтобы тратить время на выделение ресурсов, их изменение и поддержку на неопределенный срок, я решил использовать библиотеку MaterialProgressBar , которая делает это за нас:
<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"
/>
В build.gradle:
// Android horizontal ProgressBar doesn't allow removal of top/bottom padding
compile 'me.zhanghai.android.materialprogressbar:library:1.1.6'
У этого проекта есть хорошая демонстрация, которая показывает различия между ним и встроенным ProgressBar.
если кто-то все еще ищет решение - проверьте этот комментарий
установите минимальную высоту 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" />
Я использую minHeight и maxHeigh. Это помогает для разных версий 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" />
Необходимо использовать оба. Api 23 отлично работает с
android:layout_height="wrap_content"
android:minHeight="0dp"
Но более низкие версии Api увеличивают высоту индикатора выполнения до maxHeight в этом случае.
Попробуйте следующее:
<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" />
... а затем настройте индикатор выполнения в соответствии с вашими потребностями, поскольку он первоначально будет отображать полосу среднего размера с желтым оттенком прогресса с сероватым оттенком фона прогресса. Также обратите внимание, что нет вертикального отступа.
Используйте это внутри 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>
добавление android: progressDrawable в список слоев, определенный в drawable, устранило проблему для меня. Он работает, маскируя полосу прогресса в настраиваемом редактируемом
пример реализации, описанный на https://stackoverflow.com/a/4454450/1145905
Я использую, style="@style/Widget.AppCompat.ProgressBar.Horizontal"
и было довольно легко избавиться от полей. Этот стиль:
<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>
Я просто изменил минимальную / максимальную высоту:
<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" />
Нет необходимости загружать какой-либо новый модуль или даже размещать FrameLayout вокруг индикатора выполнения. Это все просто хаки. Всего 2 шага:
В вашем 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, меняйте значения как хотите.
Не любите закругленные углы?
Удалить угловой радиус
Не нравятся цвета? Поменять цвета и т.д. Готово!
<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>
Как правило, это шаги, чтобы изменить код всего, что вам не нравится. Просто найдите исходный код и подумайте, что нужно изменить. Если вы следуете исходному коду ProgressBar, вы найдете файл с именем progress_horizontal.xml, на который он ссылается. В основном, как я решаю все свои проблемы с 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"/>
Просто используйте Material ProgressIndicator, у которого нет скрытых полей.
<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" />
Простое решение без уловок, совместимое с любой версией Android и не требующее внешних библиотек, - это имитация ProgressBar
двух Views
внутренних LinearLayout
. Вот что у меня получилось. Выглядит довольно аккуратно, и этот подход довольно гибкий - вы можете анимировать его разными способами, добавлять текст и т. Д.
Планировка:
<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>
Код:
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);
}
Результат (с добавлением некоторой высоты):
Лучшее решение должно быть
android:minHeight="0dp"
Нет обходного пути и работает как шарм.
minHeight
предопределенном значении, превышающем 0 (например, 32dp, возможно). Изменив это свойство, вы получите другой вид.
maxHeight
не работает.