From e2fb5dc7798cf677f6a66b6a697c4a011b0a101f Mon Sep 17 00:00:00 2001 From: Likai Ding Date: Mon, 26 Jan 2015 10:07:21 +0800 Subject: SnapdragonCamera: fix portrait orientation Fix camera activity to portrait, so there is no delay when rotation occurs. Main changes are: 1. RotateLayout now supports padding and dynamically added child. 2. Camera controls and gesture detetion are now orientation-aware. 3. Toasts are replaced with RotateTextToast. 4. Obselete layout files are removed. Change-Id: I338849bd7fb84b847eb357f771a24a5cc09bf6fa --- src/com/android/camera/ui/CameraControls.java | 42 ++++++++++---------- src/com/android/camera/ui/CameraRootView.java | 3 +- src/com/android/camera/ui/CountDownView.java | 9 +++++ src/com/android/camera/ui/ListSubMenu.java | 20 +++++----- src/com/android/camera/ui/RotateLayout.java | 49 +++++++++++++++++++----- src/com/android/camera/ui/RotateTextToast.java | 53 ++++++++++++++++++++++---- 6 files changed, 128 insertions(+), 48 deletions(-) (limited to 'src/com/android/camera/ui') diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index 0938ffc19..dedf3d583 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import org.codeaurora.snapcam.R; import com.android.camera.ui.ModuleSwitcher; +import com.android.camera.ui.RotateImageView; import com.android.camera.ShutterButton; import com.android.camera.util.CameraUtil; @@ -80,6 +81,7 @@ public class CameraControls extends RotatableLayout { private LinearLayout mRemainingPhotos; private TextView mRemainingPhotosText; + private int mOrientation; private int mPreviewRatio; private static int mTopMargin = 0; @@ -776,34 +778,22 @@ public class CameraControls extends RotatableLayout { int h = mRemainingPhotos.getMeasuredHeight(); int m = getResources().getDimensionPixelSize(R.dimen.remaining_photos_margin); - int hc, vc; - int rotation = getUnifiedRotation(); - switch (rotation) { - case 90: - hc = (rl + rr) / 2 - m; - vc = (rt + rb) / 2; - break; - case 180: - hc = (rl + rr) / 2; - vc = (rt + rb) / 2 + m; - break; - case 270: - hc = (rl + rr) / 2 + m; - vc = (rt + rb) / 2; - break; - default: - hc = (rl + rr) / 2; - vc = (rt + rb) / 2 - m; - break; + int hc = (rl + rr) / 2; + int vc = (rt + rb) / 2 - m; + if (mOrientation == 90 || mOrientation == 270) { + vc -= w / 2; } mRemainingPhotos.layout(hc - w / 2, vc - h / 2, hc + w / 2, vc + h / 2); + mRemainingPhotos.setRotation(-mOrientation); } public void updateRemainingPhotos(int remaining) { if (remaining < 0) { mRemainingPhotos.setVisibility(View.GONE); } else { - mRemainingPhotos.setVisibility(View.VISIBLE); + for (int i = mRemainingPhotos.getChildCount() - 1; i >= 0; --i) { + mRemainingPhotos.getChildAt(i).setVisibility(View.VISIBLE); + } mRemainingPhotosText.setText(remaining + " "); } } @@ -829,6 +819,18 @@ public class CameraControls extends RotatableLayout { mRemainingPhotos.setVisibility(show ? View.GONE : View.VISIBLE); } + public void setOrientation(int orientation, boolean animation) { + mOrientation = orientation; + View[] views = { + mSceneModeSwitcher, mFilterModeSwitcher, mFrontBackSwitcher, + mHdrSwitcher, mMenu, mShutter, mPreview, mSwitcher + }; + for (View v : views) { + ((RotateImageView) v).setOrientation(orientation, animation); + } + layoutRemaingPhotos(); + } + private class ArrowTextView extends TextView { private static final int TEXT_SIZE = 14; private static final int PADDING_SIZE = 18; diff --git a/src/com/android/camera/ui/CameraRootView.java b/src/com/android/camera/ui/CameraRootView.java index daaefc027..42eebaa98 100644 --- a/src/com/android/camera/ui/CameraRootView.java +++ b/src/com/android/camera/ui/CameraRootView.java @@ -118,7 +118,7 @@ public class CameraRootView extends FrameLayout { .unregisterDisplayListener((DisplayListener) mDisplayListener); } } - +/* @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int rotation = CameraUtil.getDisplayRotation((Activity) getContext()); @@ -191,4 +191,5 @@ public class CameraRootView extends FrameLayout { } } } +*/ } diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java index d479b684a..f6d163624 100644 --- a/src/com/android/camera/ui/CountDownView.java +++ b/src/com/android/camera/ui/CountDownView.java @@ -147,4 +147,13 @@ public class CountDownView extends FrameLayout { } } } + + public void setOrientation(int orientation) { + mRemainingSecondsView.setRotation(-orientation); + if (orientation == 0) { + mCountDownTitle.setVisibility(View.VISIBLE); + } else { + mCountDownTitle.setVisibility(View.GONE); + } + } } diff --git a/src/com/android/camera/ui/ListSubMenu.java b/src/com/android/camera/ui/ListSubMenu.java index af38b162a..3501af3bc 100644 --- a/src/com/android/camera/ui/ListSubMenu.java +++ b/src/com/android/camera/ui/ListSubMenu.java @@ -80,16 +80,6 @@ public class ListSubMenu extends ListView implements } } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int screenHeight = ((LinearLayout) getParent()).getHeight(); - super.onLayout(changed, l, t, r, b); - setY(Math.max(0, mY)); - if (mY + (b - t) > screenHeight) { - setY(Math.max(0, mY - (mY + (b - t) - screenHeight))); - } - } - public void initialize(ListPreference preference, int y) { mPreference = preference; Context context = getContext(); @@ -154,4 +144,14 @@ public class ListSubMenu extends ListView implements protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } + + public int getPreCalculatedHeight() { + int count = getAdapter().getCount(); + return count * (int) getContext().getResources().getDimension(R.dimen.setting_row_height) + + (count - 1) * getDividerHeight(); + } + + public int getYBase() { + return mY; + } } diff --git a/src/com/android/camera/ui/RotateLayout.java b/src/com/android/camera/ui/RotateLayout.java index 8539eb64c..e394aba0b 100644 --- a/src/com/android/camera/ui/RotateLayout.java +++ b/src/com/android/camera/ui/RotateLayout.java @@ -22,6 +22,8 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; + // A RotateLayout is designed to display a single item and provides the // capabilities to rotate the item. public class RotateLayout extends ViewGroup implements Rotatable { @@ -42,9 +44,25 @@ public class RotateLayout extends ViewGroup implements Rotatable { @Override protected void onFinishInflate() { - mChild = getChildAt(0); - mChild.setPivotX(0); - mChild.setPivotY(0); + setupChild(getChildAt(0)); + } + + private void setupChild(View child) { + if (child != null) { + mChild = child; + child.setPivotX(0); + child.setPivotY(0); + } + } + + public void addView(View child) { + super.addView(child); + setupChild(child); + } + + public void removeView(View v) { + super.removeView(v); + mOrientation = 0; } @Override @@ -52,21 +70,22 @@ public class RotateLayout extends ViewGroup implements Rotatable { boolean change, int left, int top, int right, int bottom) { int width = right - left; int height = bottom - top; + int p = getPaddingTop(); switch (mOrientation) { case 0: case 180: - mChild.layout(0, 0, width, height); + mChild.layout(p, p, width - p, height - p); break; case 90: case 270: - mChild.layout(0, 0, height, width); + mChild.layout(p, p, height - p, width - p); break; } } @Override protected void onMeasure(int widthSpec, int heightSpec) { - int w = 0, h = 0; + int w = 0, h = 0, p = getPaddingTop(); switch(mOrientation) { case 0: case 180: @@ -81,7 +100,7 @@ public class RotateLayout extends ViewGroup implements Rotatable { h = mChild.getMeasuredWidth(); break; } - setMeasuredDimension(w, h); + setMeasuredDimension(w + 2 * p, h + 2 * p); switch (mOrientation) { case 0: @@ -109,13 +128,25 @@ public class RotateLayout extends ViewGroup implements Rotatable { return false; } - // Rotate the view counter-clockwise @Override public void setOrientation(int orientation, boolean animation) { orientation = orientation % 360; if (mOrientation == orientation) return; + + if (getParent() instanceof FrameLayout) { + int diff = (orientation - mOrientation + 360) % 360; + if (diff == 90) { + RotatableLayout.rotateCounterClockwise(this); + } else if (diff == 180) { + RotatableLayout.rotateClockwise(this); + RotatableLayout.rotateClockwise(this); + } else if (diff == 270) { + RotatableLayout.rotateClockwise(this); + } + } mOrientation = orientation; - requestLayout(); + if (mChild != null) + requestLayout(); } public int getOrientation() { diff --git a/src/com/android/camera/ui/RotateTextToast.java b/src/com/android/camera/ui/RotateTextToast.java index 10d97bf73..2bea5bbda 100644 --- a/src/com/android/camera/ui/RotateTextToast.java +++ b/src/com/android/camera/ui/RotateTextToast.java @@ -16,31 +16,51 @@ package com.android.camera.ui; +import java.util.HashSet; + import android.app.Activity; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; import com.android.camera.util.CameraUtil; import org.codeaurora.snapcam.R; public class RotateTextToast { - private static final int TOAST_DURATION = 5000; // milliseconds - ViewGroup mLayoutRoot; - RotateLayout mToast; - Handler mHandler; + private static final int LONG_DELAY = 3500; + private static final int SHORT_DELAY = 2000; + + private ViewGroup mLayoutRoot; + private RotateLayout mToast; + private Handler mHandler; + private int mDuration; + + private static HashSet mToasts = new HashSet(); + private static int mOrientation; - public RotateTextToast(Activity activity, int textResourceId, int orientation) { + private RotateTextToast(Activity activity, int duration) { mLayoutRoot = (ViewGroup) activity.getWindow().getDecorView(); LayoutInflater inflater = activity.getLayoutInflater(); View v = inflater.inflate(R.layout.rotate_text_toast, mLayoutRoot); mToast = (RotateLayout) v.findViewById(R.id.rotate_toast); + mToast.setOrientation(mOrientation, false); + mHandler = new Handler(); + mDuration = duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY; + } + + public RotateTextToast(Activity activity, CharSequence text, int duration) { + this(activity, duration); + TextView tv = (TextView) mToast.findViewById(R.id.message); + tv.setText(text); + } + + public RotateTextToast(Activity activity, int textResourceId, int duration) { + this(activity, duration); TextView tv = (TextView) mToast.findViewById(R.id.message); tv.setText(textResourceId); - mToast.setOrientation(orientation, false); - mHandler = new Handler(); } private final Runnable mRunnable = new Runnable() { @@ -48,12 +68,29 @@ public class RotateTextToast { public void run() { CameraUtil.fadeOut(mToast); mLayoutRoot.removeView(mToast); + mToasts.remove(mToast); mToast = null; } }; public void show() { + mToasts.add(mToast); mToast.setVisibility(View.VISIBLE); - mHandler.postDelayed(mRunnable, TOAST_DURATION); + mHandler.postDelayed(mRunnable, mDuration); + } + + public static RotateTextToast makeText(Activity activity, int textResourceId, int duration) { + return new RotateTextToast(activity, textResourceId, duration); + } + + public static RotateTextToast makeText(Activity activity, CharSequence text, int duration) { + return new RotateTextToast(activity, text, duration); + } + + public static void setOrientation(int orientation) { + mOrientation = orientation; + for (final RotateLayout toast: mToasts) { + toast.setOrientation(orientation, false); + } } } -- cgit v1.2.3