1c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu/*
2c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * Copyright (C) 2013 The Android Open Source Project
3c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu *
4c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
5c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * you may not use this file except in compliance with the License.
6c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * You may obtain a copy of the License at
7c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu *
8c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
9c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu *
10c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * Unless required by applicable law or agreed to in writing, software
11c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
12c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * See the License for the specific language governing permissions and
14c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * limitations under the License.
15c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu */
16c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
17c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liupackage com.android.camera.ui;
18c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
198d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liuimport android.app.Activity;
20c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.content.Context;
21c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.content.res.Configuration;
22c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.util.AttributeSet;
23c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.view.Gravity;
24c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.view.View;
258d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liuimport android.view.ViewGroup;
26c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liuimport android.widget.FrameLayout;
27c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
288d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liuimport com.android.camera.Util;
298d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu
30c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu/* RotatableLayout rotates itself as well as all its children when orientation
31c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * changes. Specifically, when going from portrait to landscape, camera
32c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * controls move from the bottom of the screen to right side of the screen
33c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * (i.e. counter clockwise). Similarly, when the screen changes to portrait, we
34c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * need to move the controls from right side to the bottom of the screen, which
35c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu * is a clockwise rotation.
36c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu */
37c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
38c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liupublic class RotatableLayout extends FrameLayout {
39c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
408d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    private static final String TAG = "RotatableLayout";
411f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu    // Initial orientation of the layout (ORIENTATION_PORTRAIT, or ORIENTATION_LANDSCAPE)
421f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu    private int mInitialOrientation;
438d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    private int mPrevRotation;
44048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    private RotationListener mListener = null;
45048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    public interface RotationListener {
46048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        public void onRotation(int rotation);
47048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    }
48c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public RotatableLayout(Context context, AttributeSet attrs, int defStyle) {
49c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        super(context, attrs, defStyle);
501f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        mInitialOrientation = getResources().getConfiguration().orientation;
51c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
52c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
53c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public RotatableLayout(Context context, AttributeSet attrs) {
54c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        super(context, attrs);
551f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        mInitialOrientation = getResources().getConfiguration().orientation;
56c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
57c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
58c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public RotatableLayout(Context context) {
59c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        super(context);
601f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        mInitialOrientation = getResources().getConfiguration().orientation;
61c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
62c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
63c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    @Override
641f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu    public void onAttachedToWindow() {
65bbbef74c4d2cbcd3c01395b02ad4534e32e9fe53Doris Liu        mPrevRotation = Util.getDisplayRotation((Activity) getContext());
661f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        // check if there is any rotation before the view is attached to window
671f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        int currentOrientation = getResources().getConfiguration().orientation;
681f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        if (mInitialOrientation == currentOrientation) {
691f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu            return;
701f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        }
711f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        if (mInitialOrientation == Configuration.ORIENTATION_LANDSCAPE
721f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu                && currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
731f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu            rotateLayout(true);
741f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        } else if (mInitialOrientation == Configuration.ORIENTATION_PORTRAIT
751f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu                && currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
761f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu            rotateLayout(false);
771f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        }
788d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    }
798d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu
808d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    @Override
81c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public void onConfigurationChanged(Configuration config) {
82c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        super.onConfigurationChanged(config);
83048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        int rotation = Util.getDisplayRotation((Activity) getContext());
841f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        if ((rotation - mPrevRotation + 360) % 180 == 0) {
859ee99847b28e9a282cf0732fa659f62a9d24f3ebDoris Liu            mPrevRotation = rotation;
861f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu            return;
871f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        }
88048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        boolean clockwise = isClockWiseRotation(mPrevRotation, rotation);
891f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        rotateLayout(clockwise);
901f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu        mPrevRotation = rotation;
911f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu    }
921f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu
931f17ec30d1b6b0d976d5dd3857bd305aaa8923eeDoris Liu    protected void rotateLayout(boolean clockwise) {
948d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        // Change the size of the layout
958d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        ViewGroup.LayoutParams lp = getLayoutParams();
968d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        int width = lp.width;
978d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        int height = lp.height;
988d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        lp.height = width;
998d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        lp.width = height;
1008d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        setLayoutParams(lp);
101048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu
1028d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        // rotate all the children
103048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        rotateChildren(clockwise);
104048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    }
105048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu
106048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    protected void rotateChildren(boolean clockwise) {
107c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int childCount = getChildCount();
108c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        for (int i = 0; i < childCount; i++) {
109c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            View child = getChildAt(i);
110c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            rotate(child, clockwise);
111c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
112048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        if (mListener != null) mListener.onRotation(clockwise ? 90 : 270);
113048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    }
114048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu
115048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    protected void flipChildren() {
116048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        mPrevRotation = Util.getDisplayRotation((Activity) getContext());
117048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        int childCount = getChildCount();
118048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        for (int i = 0; i < childCount; i++) {
119048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu            View child = getChildAt(i);
120048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu            flip(child);
121048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        }
122048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        if (mListener != null) mListener.onRotation(180);
123048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    }
124048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu
125048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    public void setRotationListener(RotationListener listener) {
126048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        mListener = listener;
127c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
128c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
1298d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    public static boolean isClockWiseRotation(int prevRotation, int currentRotation) {
1308d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        if (prevRotation == (currentRotation + 90) % 360) {
1318d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu            return true;
1328d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        }
1338d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu        return false;
1348d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu    }
1358d2d0f5f0f7fffce9dbcc70da6924af545eba26dDoris Liu
136c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public static void rotate(View view, boolean isClockwise) {
137c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (isClockwise) {
138c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            rotateClockwise(view);
139c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        } else {
140c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            rotateCounterClockwise(view);
141c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
142c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
143c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
144c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    private static boolean contains(int value, int mask) {
145c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        return (value & mask) == mask;
146c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
147c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
148c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public static void rotateClockwise(View view) {
149c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (view == null) return;
150c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        LayoutParams lp = (LayoutParams) view.getLayoutParams();
151c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int gravity = lp.gravity;
152c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int ngravity = 0;
153c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        // rotate gravity
154c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.LEFT)) {
155c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.TOP;
156c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
157c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.RIGHT)) {
158c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.BOTTOM;
159c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
160c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.TOP)) {
161c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.RIGHT;
162c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
163c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.BOTTOM)) {
164c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.LEFT;
165c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
166c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER)) {
167c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER;
168c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
169c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER_HORIZONTAL)) {
170c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER_VERTICAL;
171c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
172c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER_VERTICAL)) {
173c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER_HORIZONTAL;
174c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
175c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.gravity = ngravity;
176c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int ml = lp.leftMargin;
177c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mr = lp.rightMargin;
178c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mt = lp.topMargin;
179c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mb = lp.bottomMargin;
180c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.leftMargin = mb;
181c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.rightMargin = mt;
182c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.topMargin = ml;
183c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.bottomMargin = mr;
184c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int width = lp.width;
185c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int height = lp.height;
186c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.width = height;
187c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.height = width;
188c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        view.setLayoutParams(lp);
189c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
190c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu
191c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    public static void rotateCounterClockwise(View view) {
192c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (view == null) return;
193c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        LayoutParams lp = (LayoutParams) view.getLayoutParams();
194c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int gravity = lp.gravity;
195c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int ngravity = 0;
196c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        // change gravity
197c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.RIGHT)) {
198c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.TOP;
199c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
200c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.LEFT)) {
201c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.BOTTOM;
202c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
203c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.TOP)) {
204c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.LEFT;
205c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
206c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.BOTTOM)) {
207c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.RIGHT;
208c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
209c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER)) {
210c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER;
211c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
212c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER_HORIZONTAL)) {
213c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER_VERTICAL;
214c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
215c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        if (contains(gravity, Gravity.CENTER_VERTICAL)) {
216c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu            ngravity |= Gravity.CENTER_HORIZONTAL;
217c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        }
218c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.gravity = ngravity;
219c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int ml = lp.leftMargin;
220c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mr = lp.rightMargin;
221c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mt = lp.topMargin;
222c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int mb = lp.bottomMargin;
223c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.leftMargin = mt;
224c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.rightMargin = mb;
225c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.topMargin = mr;
226c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.bottomMargin = ml;
227c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int width = lp.width;
228c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        int height = lp.height;
229c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.width = height;
230c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        lp.height = width;
231c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu        view.setLayoutParams(lp);
232c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu    }
233048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu
234048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    // Rotate a given view 180 degrees
235048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    public static void flip(View view) {
236048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        rotateClockwise(view);
237048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu        rotateClockwise(view);
238048a61c7ab3f63688faeb39c253251e58f30c5f8Doris Liu    }
239c7fe2c5b1792edfc4054022e72ab3f45e272f361Doris Liu}