Right to Left ProgressBar?
Asked Answered
S

8

29

Does anyone know how to make a View reversed, I have a horizontal ProgressBar and I want it to right to left instead of left to right

Sather answered 7/10, 2010 at 0:11 Comment(4)
What language? What platform? What API?Moonscape
Why do you need an RTL progress bar? All the progress bars I've seen go from left to right.Aquavit
We can only answer pseudocode questions with pseudocode... otherwise please at least specify what EboMike's comment asks for.Issiah
Oh sorry, I swear I put Android. It's just for a game.Sather
S
18

Make a subclass of the normal progress bar view and implement the onDraw method to rotate the canvas before drawing it:

@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas.rotate(180,<CenterX>,<CenterY>);
    super.onDraw(canvas);
    canvas.restore();
}

This should do the trick.

Sasha answered 7/10, 2010 at 10:6 Comment(0)
C
73

It's even easier. You can simply call the following method and then it's rotated and works just how you wanted.

progressBar.setRotation(180);

An example: a normal progressbar and a RTL progressbar

Coffman answered 17/8, 2013 at 10:29 Comment(5)
should be the best answer so farUnderestimate
You can set this directly in the XML file with android:rotation="180"Fusiform
It also crashes my app. Android 6.0. Default direction is RTL, but I wanted the progress bar LTR.Necrophobia
Setting the LayoutDirection on ProgressBar object works for me.Necrophobia
In API 24 (7.0) seekbar become transparent with rotation=180Downpipe
C
34

You can flip a view in xml using scaleX or scaleY attributes

    <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleX="-1"/>
Cermet answered 3/11, 2016 at 11:39 Comment(2)
definitely should be the answerKaplan
available in circle ProgressBarMalvoisie
S
18

Make a subclass of the normal progress bar view and implement the onDraw method to rotate the canvas before drawing it:

@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas.rotate(180,<CenterX>,<CenterY>);
    super.onDraw(canvas);
    canvas.restore();
}

This should do the trick.

Sasha answered 7/10, 2010 at 10:6 Comment(0)
A
14
 public class inverseSeekBar extends ProgressBar {

public inverseSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
}

public inverseSeekBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public inverseSeekBar(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

@Override
protected synchronized void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
     canvas.save(); 

        //now we change the matrix
        //We need to rotate around the center of our text
        //Otherwise it rotates around the origin, and that's bad. 
        float py = this.getHeight()/2.0f;
        float px = this.getWidth()/2.0f;
        canvas.rotate(180, px, py); 

        //draw the text with the matrix applied. 
        super.onDraw(canvas); 

        //restore the old matrix. 
        canvas.restore(); 
}}
  <com.hlidskialf.android.widget.inverseSeekBar 

       style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="200dip"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="50"
    android:secondaryProgress="75" 

/> 

mypackage: com.test.testProgressBar

Augusto answered 7/10, 2010 at 12:47 Comment(0)
E
10

You don't need to rotate the entire View.

Just use a single xml attribute in your my_progress_drawable.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@android:id/background"
        android:drawable="@drawable/my_background"/>
    <item android:id="@android:id/progress">
        <clip
            android:drawable="@drawable/my_right_to_left_progress"
            android:gravity="right" /> <!-- Clip the image from the RIGHT -->
    </item>

</layer-list>

The documentation tells us that gravity="right" does this:

Put the object at the right edge of its container, not changing its size. When clipOrientation is "horizontal", clipping occurs at the left side of the drawable.

Don't override onDraw(). This implementation is more stable across different versions of Android.

Unfortunately, it's impossible to set the gravity of a ClipDrawable programmatically without invoking its constructor.

Edith answered 2/6, 2013 at 0:53 Comment(1)
For holo themes which use <scale> rather than <clip>, scaleGravity can be used insteadProcessional
E
8

if you want it in XML there are two properties you can use. if you want to use android:layoutDirection="rtl" it requires minimum API 17 but if you use android:rotation="180" there is no API limitation

<ProgressBar
        android:progress="20"
        android:rotation="180"
        style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
Esophagitis answered 30/3, 2018 at 7:38 Comment(0)
D
7

Cos I'm lazy I just add these two lines to the seekbar xml:

android:layoutDirection="rtl"
android:mirrorForRtl="true"

Any downsides to this?

Dubose answered 1/9, 2016 at 12:6 Comment(2)
mirrorforRtl only supports api > 18Roye
This must be the right answer if anyone is looking to switch between rtl and ltr layouts. If you want both that for LTR the progress should start from left and for RTL progress should start from right just add -> android:mirrorForRtl="true"Sporocyte
P
3

You can use android:layoutDirection="rtl"

<ProgressBar
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layoutDirection="rtl" />
Pentstemon answered 11/1, 2017 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.