7

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!

argoneus
  • 1,097
  • 2
  • 13
  • 24
  • A RelativeLayout, as its parent class ViewGroup, doesn't call onDraw by default (http://stackoverflow.com/a/13056400/1122966). I'm looking for a solution. – spacifici Jun 14 '13 at 08:14
  • Well, I am quite new to android, maybe using RelativeLayout isn't mean for these things? I just thought it gave me most flexibility in placing my elements on the screen – argoneus Jun 14 '13 at 08:17

2 Answers2

9

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

spacifici
  • 2,186
  • 2
  • 16
  • 28
  • It works! But the click areas on child View keep on same location as not rotated. How I fix that? – Idemax Jul 16 '13 at 20:49
1

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!

dbm
  • 10,376
  • 6
  • 44
  • 56
  • Argh, the "advantage" in this case is also a disadvantage... The two people don't take turns, they just click their part when appropriate >.> But this is an interesting solution, I never thought about "flipping" one part directly on the phone – argoneus Jun 14 '13 at 09:28