argoneus
argoneus

Reputation: 1147

How to rotate a RelativeLayout by 180 degrees?

I am trying to make an application, which is meant for two people and both see one half of it, so I need to flip one half vertically. I am using a LinearLayout with two RelativeLayouts inside it with layout_weight="1".

Thing is, I am not sure how to do this flip. Apparently android:rotate is only available in version 11+ (3.0+), but I would like it to support at least 2.2.

After reading other related questions on SO, I tried various things, none of which seem to work. I tried to extend the RelativeLayout and override the onDraw function, but it doesn't seem to do anything. Here's my code:

public class FlippedRelativeLayout extends RelativeLayout
{
    public FlippedRelativeLayout(Context context)
    {
        super(context);
    }

    public FlippedRelativeLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public FlippedRelativeLayout(Context context, AttributeSet attrs,
            int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        canvas.save();
        canvas.rotate(180);
        super.onDraw(canvas);
        canvas.restore();
    }
}

I will be glad for any help, thanks!

Upvotes: 7

Views: 2370

Answers (2)

spacifici
spacifici

Reputation: 2186

Try this:

public class MyRelativeLayout extends RelativeLayout {    
    public MyRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public MyRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyRelativeLayout(Context context) {
        super(context);
        init();
    }

    private void init() {
        setStaticTransformationsEnabled(true);
    }

    @Override
    protected boolean getChildStaticTransformation(View child, Transformation t) {
        t.setTransformationType(Transformation.TYPE_MATRIX);
        Matrix m = t.getMatrix();
        m.reset();
        m.postRotate(180, child.getWidth() / 2.0f, child.getHeight() / 2.0f);
        return true;
    }
}

The result is: enter image description here

Upvotes: 9

dbm
dbm

Reputation: 10485

Very interesting question!

You could perhaps try to create two partly transparant Activity-s, showing their own copy of the same layout xml and then switching the "z-order" of the active Activity depending on whos turn it is to make a move.

Activity A would be "your own" activity and it would have a transparent top half and the RelativeLayout as it's bottom half. It would also have a normal screen orientation, like: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT).

Activity B would be "your opponents activity". It would also have a transparent top half and a copy of the very same RelativeLayout as it's bottom part. It would however have an inverted screen orientation, like: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT). This would mean that the transparent part of Activity B would overlap the RelativeLayout part of Activity A, and the transparent part of Activity A would overlap the RelativeLayout part of Activity B.

You could also put the corresponding launch mode of the Activity-s to "single top" or some other suitable value, so you don't create a new instance of your Activity when "starting it again", i.e. passing on the "make-a-move-ticket" to the opponent.

Unfortunately the ...REVERSE_PORTRAIT orientation wasn't added until API level 9 (Android 2.3.something) and you explicitely request API level 8.

The neat part about this approach would be that since only one Activity can have focus (and, hence, take input) at a time, you would automatically get a statemachine for the user input: the opponent wouldn't have the possibility to interact with his/her board until you've made your move and vice versa.

Hope this gives you some ideas at least.

Cheers!

Upvotes: 1

Related Questions