Ответ 1
По умолчанию вертикальные полосы выполнения не поддерживаются.
Я пытаюсь использовать ProgressBar в качестве показателя, например дисплея. Я думал, что это будет легкая задача, и подумал, что у ProgressBar есть свойство устанавливать вертикальное, но я ничего не вижу.
Кроме того, я хотел бы показать индикатор линейки, расположенный рядом с панелью, чтобы четко обозначать текущий уровень.
Указатели оценили - Спасибо!
По умолчанию вертикальные полосы выполнения не поддерживаются.
Недавно я столкнулся с необходимостью вертикального индикатора выполнения, но не смог найти решение, используя существующий виджет Progress Bar. Решения, с которыми я столкнулся, обычно требовали расширения текущей панели прогресса или совершенно нового класса в ней. Я не был уверен, что выкатывать новый класс для достижения простого изменения ориентации было необходимо.
В этой статье представлено простое, элегантное и, самое главное, решение без хака для достижения вертикального индикатора выполнения. Я собираюсь пропустить объяснение и просто предоставить решение для резака для печенья. Если вам нужна дополнительная информация, свяжитесь со мной или оставьте комментарий ниже.
Создайте xml в своей выпадающей папке (не drawable-hdpi или drawable-mdpi - поместите его в drawable). В этом примере я вызываю свой xml vertical_progress_bar.xml
Вот что разместить в 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>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="180"
/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip android:clipOrientation="vertical" android:gravity="bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="180"
/>
</shape>
</clip>
</item>
</layer-list>
Создайте xml файл с именем styles.xml и поместите его в res/values. Если в вашем проекте уже есть styles.xml в res/values, пропустите этот шаг.
Измените файл styles.xml и добавьте следующий код в конец файла:
<style name="Widget">
</style>
<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
<item name="android:minWidth">48dip</item>
<item name="android:maxWidth">48dip</item>
<item name="android:minHeight">48dip</item>
<item name="android:maxHeight">48dip</item>
</style>
<style name="Widget.ProgressBar.Vertical">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/progress_bar_vertical</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minWidth">1dip</item>
<item name="android:maxWidth">12dip</item>
</style>
Добавьте свой новый вертикальный индикатор выполнения в свой макет. Вот пример:
<ProgressBar
android:id="@+id/vertical_progressbar"
android:layout_width="12dip"
android:layout_height="300dip"
style="@style/Widget.ProgressBar.Vertical"
/>
Это должно быть все, что вам нужно сделать, чтобы использовать вертикальный индикатор выполнения в вашем проекте. Возможно, у вас могут быть пользовательские графические изображения с девятью патчами, которые вы используете для индикатора выполнения. Вы должны внести соответствующие изменения в файл progress_bar_vertical.xml. Надеюсь, это поможет вам в вашем проекте!
Вам нужно создать свой собственный пользовательский индикатор прогресса.
В xml добавьте этот макет:
<com.example.component.VerticalProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/verticalRatingBar1"
android:layout_width="wrap_content"
android:progress="50"
android:layout_height="fill_parent" />
VerticalProgressBar.java
public class VerticalProgressBar extends ProgressBar{
private int x, y, z, w;
@Override
protected void drawableStateChanged() {
// TODO Auto-generated method stub
super.drawableStateChanged();
}
public VerticalProgressBar(Context context) {
super(context);
}
public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
this.x = w;
this.y = h;
this.z = oldw;
this.w = oldh;
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setSelected(true);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
setProgress(getMax()
- (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
setSelected(false);
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
@Override
public synchronized void setProgress(int progress) {
if (progress >= 0)
super.setProgress(progress);
else
super.setProgress(0);
onSizeChanged(x, y, z, w);
}
}
Или: Решение Jagsaund также прекрасно.
Я знаю, что это старый пост, но я нашел очень простое решение этой проблемы, которое может кому-то помочь. Сначала создайте файл progress_drawable_vertical.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">
<color android:color="#777" />
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000"
android:angle="90" />
</shape>
</clip>
</item>
</layer-list>
Тогда просто используйте это в вашем прогрессбар:
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:max="100"
android:progress="33"
android:progressDrawable="@drawable/progress_drawable_vertical" />
Я также создал progress_drawable_horizont.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">
<color android:color="#777" />
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left">
<shape>
<gradient
android:startColor="#00FF00"
android:centerColor="#FFFF00"
android:endColor="#FF0000" />
</shape>
</clip>
</item>
</layer-list>
с целью сохранения стиля, определенного в progress_drawable_vertical.xml
Ключевым моментом здесь является правильное использование android:clipOrientation
и android:gravity
.
Я нашел это решение здесь, и суть решения похожа на jagsaund, но немного проще.
Я нашел наиболее подходящее (самое простое и универсальное) решение:)
Это старый пост, но мне было так трудно найти это так простое решение, поэтому я подумал, что должен его опубликовать.
Просто используйте scale-drawable
(или 9-патч, если хотите), не нужно ЛЮБОГО ДРУГОГО кода.
Пример:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background" android:drawable="@color/transparent"/>
<item android:id="@android:id/progress">
<scale android:scaleGravity="bottom" android:scaleWidth="0%" android:scaleHeight="100%">
<shape >
<solid android:color="@color/blue"/>
<corners android:topRightRadius="1dp" android:topLeftRadius="1dp"/>
</shape>
</scale>
</item>
</layer-list>
И, конечно, обычный код:
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="24dp"
android:layout_height="match_parent"
android:max="1000"
android:progress="200"
android:progressDrawable="@drawable/progress_scale_drawable" />
Обратите внимание на строки scale-drawable
xml (магические линии):
android:scaleGravity="bottom" //scale from 0 in y axis (default scales from center Y)
android:scaleWidth="0%" //don't scale width (according to 'progress')
android:scaleHeight="100%" //do scale the height of the drawable
This perfectly works
<?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>
<gradient
android:startColor="#DDDDDD"
android:centerColor="#DDDDDD"
android:centerY="0.75"
android:endColor="#DDDDDD"
android:angle="270"
/>
</shape>
</item>
<item
android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="top">
<shape>
<gradient
android:angle="0"
android:startColor="#302367"
android:centerColor="#7A5667"
android:endColor="#C86D67"/>
</shape>
</clip>
</item>
</layer-list>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="5dp"
android:layout_height="match_parent"'enter code here'
android:progressDrawable="@drawable/progress_dialog"/>
Чтобы использовать ProgressBar и сделать его вертикальным, вам нужно будет создать свой собственный пользовательский вид, расширяющий представление ProgressBar и переопределяя метод onDraw(). Это позволит вам рисовать его в обратной ориентации. Взгляните на исходный код ProgressBar.onDraw()
(расположенный внизу ссылки) для получения справки о том, как это сделать. Лучший сценарий, вам просто придется поменять несколько переменных x и y.
Создание индикатора выполнения (я преобразовал свой код из С# в java, поэтому не может быть на 100% правильным)
ProgressBar progBar = new ProgressBar(Context, null, Android.resource.attribute.progressDrawable);
progBar.progressDrawable = ContextCompat.getDrawable(Context, resource.drawable.vertical_progress_bar);
progBar.indeterminate = false;
vertical_progress_bar.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="@color/grey" />
<corners android:radius="20dip" />
</shape>
</item>
<item android:id="@android:id/progress">
<scale
android:drawable="@drawable/vertical_progress_bar_blue_progress"
android:scaleHeight="100%"
android:scaleGravity="bottom"/>
</item>
</layer-list>
vertical_progress_bar_blue_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners
android:radius="20dip" />
<solid android:color="@color/ProgressBarFourth" />
</shape>
Что нужно сделать, чтобы ваша вертикальная панель была атрибутами scaleHeight
и scaleGravity
в vertical_progress_bar.xml
.
В результате он выглядит примерно так:
У меня есть точная проблема. Создание пользовательского класса (расширение ProgressBar) приведет к созданию кода, который трудно поддерживать. Использование пользовательского стиля вызовет проблему совместимости с другой темой из новой ОС (например, леденец)
В конце концов, я просто применил анимацию вращения к горизонтальной панели выполнения. Вдохновленный Пит.
код:
private void setProgress(final ProgressBar progressBar, int progress) {
progressBar.setWillNotDraw(true);
progressBar.setProgress(progress);
progressBar.setWillNotDraw(false);
progressBar.invalidate();
}
private void rotateView(final View v, float degree) {
Animation an = new RotateAnimation(0.0f, degree);
an.setDuration(0);
an.setRepeatCount(0);
an.setFillAfter(true); // keep rotation after animation
v.setAnimation(an);
}
Простой просмотр изображения в режиме прожектора
Пример
viewHolder.proBarTrueImage.setMaximalValue(147);
viewHolder.proBarTrueImage.setLevel(45);
viewHolder.proBarTrueImage.setColorResource(R.color.corner_blue);
простой класс
public class ProgressImageView extends ImageView {
private Context mContext;
private Paint paint;
private RectF rectf;
private int maximalValue = 1;
private int level = 0;
private int width;
private int height;
public ProgressImageView(Context context) {
super(context);
init(context, null, 0);
}
public ProgressImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ProgressImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr){
mContext = context;
paint = new Paint();
rectf = new RectF();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.FILL);
};
@Override
protected void onDraw(Canvas canvas) {
float dif = (float) height / (float) maximalValue;
int newHeight = height - (int) (dif * level);
rectf.set(0,newHeight, width, height);
canvas.drawRect(rectf, paint);
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.width = w;
this.height = h;
}
public void setMaximalValue(int maximalValue) {
this.maximalValue = maximalValue;
invalidate();
}
public void setLevel(int level) {
this.level = level;
invalidate();
}
public void setColorResource(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
color = mContext.getResources().getColor(color,mContext.getTheme());
}else {
color = mContext.getResources().getColor(R.color.corner_blue);
}
setColor(color);
}
public void setColor(int color){
if (paint != null){
paint.setColor(color);
invalidate();
}
}
}
** Проверьте эту ссылку, я пытался использовать аналогичную вещь, и вы также можете использовать степпер для ваших нужд, на Github доступно несколько проектов о том, КАК ИСПОЛЬЗОВАТЬ STEPPER В ANDROID STUDIO **
Добавьте это в код XML Android: вращение = "90" андроид: transformPivotX = "0dp" Так вот как должен выглядеть ваш Progress Bar xml
<ProgressBar
android:id="@+id/progressBar6"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="90"
android:transformPivotX="0dp"
tools:layout_editor_absoluteX="101dp"
tools:layout_editor_absoluteY="187dp" />
Вот простое решение, просто поверните индикатор выполнения
android:rotation="270"
<ProgressBar
android:id="@+id/battery_pb"
android:rotation="270"
android:progress="100"
...
/>
Используйте android: вращение = "270" до 100%, как внизу вверх или андроид: вращение = "90" до 100%, как сверху вниз