Intereting Posts
Android прокручивает, используя ViewPager без вкладок Как установить onClickListener на ArrayAdapter? Android Studio stale APK для варианта сборки после изменения xml Что такое замена устаревших MODE_WORLD_READABLE SharedPreferences в Android? Ошибка сеанса «приложение» при установке APK «GoogleApiClient еще не подключен» исключение в приложении Cast Есть ли способ предотвратить пересканирование списка в верхнее положение при изменении данных адаптера? Как реализовать салфетку между Фрагментами? Могу ли я заставить пользователя согласиться с юридической оговоркой перед установкой приложения для Android? Android: дочерние элементы разделяют нажатие на состояние со своим родителем, даже если duplicateParentState указан Android: Каковы рекомендуемые конфигурации Proguard? Приложение для потокового видео на Android Приложение Facebook является общедоступным, но при входе в систему появляется сообщение об ошибке «Приложение не настроено» Android http-тестирование с помощью Robolectric Android – Сохранить изображение с URL на SD-карту

Закругленный прогресс в пределах округленного шага выполнения

Я пытаюсь создать пользовательский индикатор выполнения в приложении, над которым мы работаем, и последний элемент, который мне нужен, – это индикатор прогресса. Вместо этого я хочу, чтобы этот бар закруглялся точно так же, как левый и правый края самого индикатора выполнения, как во втором изображении (за вычетом красного круга, конечно).

Введите описание изображения здесь

Введите описание изображения здесь

Вот определение макета индикатора выполнения (остальная часть файла макета опущена для краткости):

<ProgressBar android:id="@+id/progress_bar" android:layout_width="fill_parent" android:layout_height="60dp" android:padding="3dp" android:max="100" android:progressDrawable="@drawable/progress_bar_states" android:layout_marginTop="10dp" style="?android:attr/progressBarStyleHorizontal" android:indeterminateOnly="false" android:layout_below="@id/textview2" android:layout_alignLeft="@id/textview2" /> 

И вот файл progress_bar_states.xml:

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="#20ffff00"/> <corners android:radius="60dp"/> </shape> </item> <item android:id="@android:id/progress"> <clip> <shape> <solid android:color="#20ffffff"/> <corners android:radius="60dp"/> </shape> </clip> </item> </layer-list> 

Как мне это сделать? Я не вижу никаких параметров, позволяющих мне определить индикатор прогресса вообще. Должен ли я делать это по-другому? Я все еще довольно новичок в Android, поэтому любое руководство ценится.

@Ando – ваше решение очень близко к тому, что мне нужно. Сейчас начинается движение индикаторов, и я предполагаю, что это не клип, как оригинал. Когда индикатор начинает и до некоторой точки в начале, похоже, что он «сжат»,

Введите описание изображения здесь

Пока он не доберется до соответствующей точки, тогда он выглядит хорошо:

Введите описание изображения здесь

Как мы можем выполнить «отсечение» в начале этого решения?

Для @bladefury – как вы можете видеть, по сравнению с передним краем изображения выше, он, похоже, сглаживается.

Введите описание изображения здесь

EDIT: не смотря на это довольно долгое время, я посмотрел новый компонент на https://github.com/akexorcist/Android-RoundCornerProgressBar/issues , и у него такая же проблема, как и предложения здесь.

Solutions Collecting From Web of "Закругленный прогресс в пределах округленного шага выполнения"

Вы можете использовать эту библиотеку для выполнения шага выполнения закругленного угла

 <com.akexorcist.roundcornerprogressbar.RoundCornerProgressBar android:layout_width="dimension" android:layout_height="dimension" app:rcProgress="float" app:rcSecondaryProgress="float" app:rcMax="float" app:rcRadius="dimension" app:rcBackgroundPadding="dimension" app:rcReverse="boolean" app:rcProgressColor="color" app:rcSecondaryProgressColor="color" app:rcBackgroundColor="color" /> 

Gradle

 compile 'com.akexorcist:RoundCornerProgressBar:2.0.3' 

https://github.com/akexorcist/Android-RoundCornerProgressBar

Просто измените файл progress_bar_states.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> <solid android:color="#20ffff00" /> <corners android:radius="20dp" /> </shape> </item> <item android:id="@android:id/progress"> <!-- <clip> --> <!-- <shape> --> <!-- <solid android:color="@android:color/black" /> --> <!-- <corners --> <!-- android:bottomRightRadius="30dp" --> <!-- android:radius="60dp" --> <!-- android:topRightRadius="30dp" /> --> <!-- </shape> --> <!-- </clip> --> <scale android:drawable="@drawable/custom_progress_primary" android:scaleWidth="98%" /><!-- change here --> </item> 

Здесь custom_progress_primary.xml файл: как показано ниже

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp" /> <solid android:color="@android:color/white" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape> 1 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp" /> <solid android:color="@android:color/white" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape> 

Вариант, который, возможно, немного более практичен, – это создание настраиваемого представления панели выполнения.

 public class CustomProgressBar extends View { // % value of the progressbar. int progressBarValue = 0; public CustomProgressBar(Context context) { super(context); } public CustomProgressBar(Context context, AttributeSet attrs) { super(context, attrs); progressBarValue = attrs.getAttributeIntValue(null, "progressBarValue", 0); } public void setValue(int value) { progressBarValue = value; invalidate(); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); float cornerRadius = 30.0f; // Draw the background of the bar. Paint backgroundPaint = new Paint(); backgroundPaint.setColor(Color.LTGRAY); backgroundPaint.setStyle(Paint.Style.FILL); backgroundPaint.setAntiAlias(true); RectF backgroundRect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight()); canvas.drawRoundRect(backgroundRect, cornerRadius, cornerRadius, backgroundPaint); // Draw the progress bar. Paint barPaint = new Paint(); barPaint.setColor(Color.GREEN); barPaint.setStyle(Paint.Style.FILL); barPaint.setAntiAlias(true); float progress = (backgroundRect.width() / 100) * progressBarValue; RectF barRect = new RectF(0, 0, progress, canvas.getClipBounds().bottom); canvas.drawRoundRect(barRect, cornerRadius, cornerRadius, barPaint); // Draw progress text in the middle. Paint textPaint = new Paint(); textPaint.setColor(Color.WHITE); textPaint.setTextSize(34); String text = progressBarValue + "%"; Rect textBounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), textBounds); canvas.drawText(text, backgroundRect.centerX() - (textBounds.width() / 2), backgroundRect.centerY() + (textBounds.height() / 2), textPaint); } } 

Затем в вашем макете:

 <view.CustomProgressBar android:layout_height="30dp" android:layout_width="match_parent" progressBarValue="66"/> 

Что дает результат:

Результат пользовательского выполнения

ProgressBar использует ClipDrawable , который позволяет кликать с прямоугольником. Таким образом, вы можете установить drawable, который скопирует круглый прямоугольник угла в индикатор выполнения, и вот как это сделать:

Во-первых, удалите <clip> в вашем индикаторе выполнения:

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="#20ffff00"/> <corners android:radius="60dp"/> </shape> </item> <item android:id="@android:id/progress"> <shape> <solid android:color="#20ffffff"/> <corners android:radius="60dp"/> </shape> </item> 

Затем увеличьте индикатор выполнения следующим образом:

 public class RoundIndicatorProgressBar extends ProgressBar { private static final float CORNER_RADIUS_DP = 60.0f; public RoundIndicatorProgressBar(Context context) { this(context, null); } public RoundIndicatorProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundIndicatorProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setProgressDrawable(Drawable d) { super.setProgressDrawable(tileify(d, false)); } private Drawable tileify(Drawable drawable, boolean clip) { if (drawable instanceof LayerDrawable) { LayerDrawable background = (LayerDrawable) drawable; final int N = background.getNumberOfLayers(); Drawable[] outDrawables = new Drawable[N]; for (int i = 0; i < N; i++) { int id = background.getId(i); outDrawables[i] = tileify(background.getDrawable(i), (id == android.R.id.progress || id == android.R.id.secondaryProgress)); } LayerDrawable newBg = new LayerDrawable(outDrawables); for (int i = 0; i < N; i++) { newBg.setId(i, background.getId(i)); } return newBg; } else { if (clip) { return new RoundClipDrawable(drawable, dp2px(getContext(), CORNER_RADIUS_DP)); } } return drawable; } public static float dp2px(Context context, float dp) { final float scale = context.getResources().getDisplayMetrics().density; return dp * scale; } } 

И здесь RoundClipDrawable , измененный из ClipDrawable :

RoundClipDrawable.java Gist

Вы можете использовать

Проверьте мой пост здесь: https://stackoverflow.com/a/41206481/6033946

Попробуйте это, вы можете сделать то, что хотите, изменив цвет, ширину и высоту большого пальца и строку поиска в xml.

Как мы можем выполнить «отсечение» в начале этого решения?

Вам нужно ограничить минимальное значение прогресса, например:

 final int minProgress = pb.getMax() * {20dp} / pb.getWidth(); progress = Math.max(minProgress, progress); pb.setProgress(progress); 

Использовать вышеприведенный код для постпроцесса вашего значения прогресса – это нормально. Это не тягостная ошибка, а правильный эффект растяжения.