Android - set a ProgressBar to be a vertical bar instead of horizontal?

后端 未结 14 614
不知归路
不知归路 2020-11-30 22:22

I am trying to use a ProgressBar as a metering like display. I thought it was going to be an easy task and thought that ProgressBar had a property to set to be vertical, bu

相关标签:
14条回答
  • 2020-11-30 23:02

    I have the exact problem. Making a custom class (extending ProgressBar) will create code that are hard to maintain. Using a custom style will cause compatibility issue with different theme from new OS (e.g. lollipop)

    Eventually, I just apply a rotation animation to an horizontal progress bar. Inspired by Pete.

    1. Create the tag in your layout xml like normal horizontal progress bar.
    2. Make sure that the size and position of the ProgressBar is what you want after rotation. (Perhaps setting negative margin will help). In my code I rotate the view from 0,0.
    3. Use the method below to rotate and set new progress.

    Code:

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 23:02
    <ProgressBar
            android:id="@+id/battery_pb"
            android:rotation="270"
            android:progress="100"
    ...
    />
    

    Use android:rotation="270" to 100% be like bottom to top or android:rotation="90" to 100% be like top to bottom

    0 讨论(0)
  • 2020-11-30 23:07

    Simple progrebar image view

    example

    viewHolder.proBarTrueImage.setMaximalValue(147);
    viewHolder.proBarTrueImage.setLevel(45);
    viewHolder.proBarTrueImage.setColorResource(R.color.corner_blue);
    

    simple class

    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();
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-30 23:10

    I found the probably best(easiest & most versatile) solution:)

    This is an old post, but it was so hard for me to find this so easy solution so I thought I should post it..

    Just use a scale-drawable (or a 9-patch if you want), no need for ANY OTHER code.

    Example:

    <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>  
    

    And of course the normal code:

    <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" />  
    

    Notice the scale-drawable's xml lines (the magic lines):

    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
    
    0 讨论(0)
  • 2020-11-30 23:10
    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"/>
    
    0 讨论(0)
  • 2020-11-30 23:10

    Creating the progress bar (I converted my code from c# to java so might not be 100% correct)

    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>
    

    What's going to make your bar vertical is the scaleHeight and scaleGravity attributes in vertical_progress_bar.xml.

    It ends up looking something like this:

    0 讨论(0)
提交回复
热议问题