summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndy Mast <andy@cyngn.com>2014-07-09 14:37:24 -0700
committerAndy Mast <andy@cyngn.com>2014-07-10 10:14:14 -0700
commit36f745ed8c21c4bbb05cf99ed9f0b4fd1c8d448d (patch)
treee4a821e1ec4647a4caeefe408fa22633e72dfee7 /src
parent081ade0e9c9264a0c72501cf077d0c9c845d318d (diff)
downloadpackages_apps_ThemeChooser-36f745ed8c21c4bbb05cf99ed9f0b4fd1c8d448d.zip
packages_apps_ThemeChooser-36f745ed8c21c4bbb05cf99ed9f0b4fd1c8d448d.tar.gz
packages_apps_ThemeChooser-36f745ed8c21c4bbb05cf99ed9f0b4fd1c8d448d.tar.bz2
Theme component cards
Change-Id: I31b3102a6b578974a6b0f11116dce052c83bce73
Diffstat (limited to 'src')
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java21
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java90
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/PagerContainer.java24
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java146
4 files changed, 222 insertions, 59 deletions
diff --git a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java b/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
index ee60286..05aa1ae 100644
--- a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
+++ b/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
@@ -82,7 +82,7 @@ public class ChooserActivity extends FragmentActivity
DisplayMetrics dm = getResources().getDisplayMetrics();
int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, dm);
- mPager.setPageMargin(margin);
+ mPager.setPageMargin(-margin / 2);
mPager.setOffscreenPageLimit(3);
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@@ -187,10 +187,14 @@ public class ChooserActivity extends FragmentActivity
hideSaveApplyButton();
} else if (mExpanded) {
mExpanded = false;
- mContainer.collapse();
- ThemeFragment f = (ThemeFragment) getSupportFragmentManager()
+ final ThemeFragment f = (ThemeFragment) getSupportFragmentManager()
.findFragmentByTag(getFragmentTag(mPager.getCurrentItem()));
- f.collapse();
+ f.fadeOutCards(new Runnable() {
+ public void run() {
+ mContainer.collapse();
+ f.collapse();
+ }
+ });
} else {
super.onBackPressed();
}
@@ -261,17 +265,12 @@ public class ChooserActivity extends FragmentActivity
private View.OnClickListener mPagerClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- mExpanded = !mExpanded;
- if (mExpanded) {
+ if (!mExpanded) {
+ mExpanded = true;
mContainer.expand();
ThemeFragment f = (ThemeFragment) getSupportFragmentManager()
.findFragmentByTag(getFragmentTag(mPager.getCurrentItem()));
f.expand();
- } else {
- mContainer.collapse();
- ThemeFragment f = (ThemeFragment) getSupportFragmentManager()
- .findFragmentByTag(getFragmentTag(mPager.getCurrentItem()));
- f.collapse();
}
}
};
diff --git a/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java b/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java
new file mode 100644
index 0000000..8a56093
--- /dev/null
+++ b/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java
@@ -0,0 +1,90 @@
+package org.cyanogenmod.theme.chooserv2;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.drawable.TransitionDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.cyanogenmod.theme.chooser.R;
+
+public class ComponentCardView extends LinearLayout {
+ public static final int CARD_FADE_DURATION = 300;
+
+ private TextView mLabel;
+
+ // Expanded Padding
+ int mExpandPadLeft;
+ int mExpandPadTop;
+ int mExpandPadRight;
+ int mExpandPadBottom;
+
+ public ComponentCardView(Context context) {
+ this(context, null);
+ }
+
+ public ComponentCardView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ComponentCardView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mLabel = (TextView) findViewById(R.id.label);
+
+ Resources r = getContext().getResources();
+ mExpandPadLeft =
+ (int) r.getDimension(R.dimen.card_padding_left_right) + getPaddingLeft();
+ mExpandPadTop =
+ (int) r.getDimension(R.dimen.card_padding_top) + getPaddingTop();
+ mExpandPadRight =
+ (int) r.getDimension(R.dimen.card_padding_left_right) + getPaddingRight();
+ mExpandPadBottom =
+ (int) r.getDimension(R.dimen.card_padding_bottom) + getPaddingBottom();
+ }
+
+ public void expand() {
+ TransitionDrawable bg = (TransitionDrawable) getBackground();
+ Rect paddingRect = new Rect();
+ bg.getPadding(paddingRect);
+
+ setPadding(mExpandPadLeft, mExpandPadTop, mExpandPadRight, mExpandPadBottom);
+
+ if (mLabel != null) {
+ mLabel.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void animateExpand() {
+ if (getBackground() instanceof TransitionDrawable) {
+ TransitionDrawable background = (TransitionDrawable) getBackground();
+ if (mLabel != null) {
+ mLabel.setVisibility(View.VISIBLE);
+ mLabel.animate().alpha(1f).setDuration(CARD_FADE_DURATION);
+ }
+ background.startTransition(CARD_FADE_DURATION);
+ }
+ }
+
+ public void collapse() {
+ if (mLabel != null) {
+ mLabel.setVisibility(View.GONE);
+ }
+ setPadding(0, 0, 0, 0);
+ }
+
+ public void animateFadeOut() {
+ if (mLabel != null) {
+ mLabel.animate().alpha(0f).setDuration(CARD_FADE_DURATION);
+ }
+ TransitionDrawable background = (TransitionDrawable) getBackground();
+ background.reverseTransition(CARD_FADE_DURATION);
+ }
+
+}
diff --git a/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java b/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java
index f58957f..f6cd8ef 100644
--- a/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java
+++ b/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java
@@ -133,9 +133,30 @@ public class PagerContainer extends FrameLayout implements ViewPager.OnPageChang
setLayoutParams(params);
mPager.setExpanded(true);
+
final int current = mPager.getCurrentItem();
final int prevY = (int) getY();
+ //Since our viewpager's width is changing to fill the screen
+ //we must start the left/right children of the current page inwards on first draw
+ final int lChildPrevXf;
+ final int rChildPrevXf;
+
+ if (current != 0) {
+ final View lchild = mPager.getViewForPosition(current - 1);
+ lChildPrevXf = (int) lchild.getX();
+ } else {
+ lChildPrevXf = 0;
+ }
+
+ if (current < mPager.getAdapter().getCount() - 1) {
+ View rchild = mPager.getViewForPosition(current + 1);
+ rChildPrevXf = (int) rchild.getX();
+ } else {
+ rChildPrevXf = 0;
+ }
+
+
final ViewTreeObserver observer = mPager.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
@@ -143,11 +164,13 @@ public class PagerContainer extends FrameLayout implements ViewPager.OnPageChang
if (current != 0) {
View lchild = mPager.getViewForPosition(current - 1);
lchild.setTranslationY(prevY - getY());
+ lchild.setX(lChildPrevXf);
animateChildOut(lchild, -getWidth());
}
if (current < mPager.getAdapter().getCount() - 1) {
View rchild = mPager.getViewForPosition(current + 1);
+ rchild.setX(rChildPrevXf);
rchild.setTranslationY(prevY - getY());
animateChildOut(rchild, getWidth());
}
@@ -166,7 +189,6 @@ public class PagerContainer extends FrameLayout implements ViewPager.OnPageChang
final int prevY = (int) getY();
if (current != 0) {
-
View lchild = mPager.getViewForPosition(current - 1);
lchild.setTranslationY(0);
animateChildIn(lchild);
diff --git a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java b/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
index c716c7b..4fa467a 100644
--- a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
+++ b/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
@@ -24,11 +24,13 @@ import android.content.res.ThemeConfig;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.provider.Settings;
import android.provider.ThemesContract;
import android.provider.ThemesContract.PreviewColumns;
@@ -37,7 +39,6 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
-import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -57,7 +58,7 @@ import java.util.List;
public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
public static final int ANIMATE_START_DELAY = 200;
- public static final int ANIMATE_DURATION = 800;
+ public static final int ANIMATE_DURATION = 300;
public static final int ANIMATE_INTERPOLATE_FACTOR = 3;
public static final String CURRENTLY_APPLIED_THEME = "currently_applied_theme";
@@ -109,6 +110,8 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
private ImageView mHomeButton;
private ImageView mRecentButton;
+ private Handler mHandler;
+
static ThemeFragment newInstance(String pkgName) {
ThemeFragment f = new ThemeFragment();
Bundle args = new Bundle();
@@ -132,6 +135,8 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
helper.load(getActivity(), CURRENTLY_APPLIED_THEME.equals(mPkgName) ?
getAppliedFontPackageName() : mPkgName);
mTypefaceNormal = helper.getTypeface(Typeface.NORMAL);
+
+ mHandler = new Handler();
}
@Override
@@ -179,61 +184,99 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
}
public void expand() {
- ViewGroup.LayoutParams layoutParams = mScrollContent.getLayoutParams();
- layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
- mScrollContent.setLayoutParams(layoutParams);
-
- layoutParams = mPreviewContent.getLayoutParams();
+ // Full width and height!
+ ViewGroup content = (ViewGroup) mScrollView.getParent();
+ content.setPadding(0, 0, 0, 0);
+ ViewGroup.LayoutParams layoutParams = mPreviewContent.getLayoutParams();
layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ // Expand the children
for (int i = 0; i < mPreviewContent.getChildCount(); i++) {
- View child = mPreviewContent.getChildAt(i);
- RelativeLayout.LayoutParams layout =
+ ComponentCardView child = (ComponentCardView) mPreviewContent.getChildAt(i);
+ RelativeLayout.LayoutParams lparams =
(RelativeLayout.LayoutParams) child.getLayoutParams();
- int botMargin = (int) child.getContext().getResources()
- .getDimension(R.dimen.expanded_preview_margin);
- layout.setMargins(0, 0, 0, botMargin);
- child.setLayoutParams(layout);
+
+ int top = (int) child.getResources()
+ .getDimension(R.dimen.expanded_card_margin_top);
+ lparams.setMargins(0, top, 0, 0);
+ if (child.getId() == R.id.navigation_bar_container) {
+ lparams.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+ lparams.addRule(RelativeLayout.BELOW, R.id.icon_container);
+ }
+
+ child.setLayoutParams(lparams);
+ child.expand();
}
- mScrollContent.requestLayout();
- animateChildren(true);
+
+ // Collect the present position of all the children. The next layout/draw cycle will
+ // change these bounds since we just expanded them. Then we can animate from prev location
+ // to the new location.
+ animateChildren(true, getChildrensGlobalBounds());
animateWallpaperOut();
+ }
+ // Returns the boundaries for all the children in the scrollview relative to the window
+ private List<Rect> getChildrensGlobalBounds() {
+ List<Rect> bounds = new ArrayList<Rect>();
+ for (int i = 0; i < mPreviewContent.getChildCount(); i++) {
+ final View v = mPreviewContent.getChildAt(i);
+ int[] pos = new int[2];
+ v.getLocationInWindow(pos);
+ Rect boundary = new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight());
+ bounds.add(boundary);
+ }
+ return bounds;
+ }
+
+ public void fadeOutCards(Runnable endAction) {
+ for (int i = 0; i < mPreviewContent.getChildCount(); i++) {
+ ComponentCardView v = (ComponentCardView) mPreviewContent.getChildAt(i);
+ v.animateFadeOut();
+ }
+ mHandler.postDelayed(endAction, ComponentCardView.CARD_FADE_DURATION);
}
public void collapse() {
+ // Pad the view so it appears thinner
+ ViewGroup content = (ViewGroup) mScrollView.getParent();
+ Resources r = mScrollView.getContext().getResources();
+ int leftRightPadding = (int) r.getDimension(R.dimen.collapsed_theme_page_padding);
+ content.setPadding(leftRightPadding, 0, leftRightPadding, 0);
+
+ // Shrink the height
ViewGroup.LayoutParams layoutParams = mPreviewContent.getLayoutParams();
Resources resources = mPreviewContent.getResources();
layoutParams.height = (int) resources.getDimension(R.dimen.theme_preview_height);
for (int i = 0; i < mPreviewContent.getChildCount(); i++) {
- View child = mPreviewContent.getChildAt(i);
- RelativeLayout.LayoutParams layout =
+ ComponentCardView child = (ComponentCardView) mPreviewContent.getChildAt(i);
+ RelativeLayout.LayoutParams lparams =
(RelativeLayout.LayoutParams) child.getLayoutParams();
- layout.setMargins(0, 0, 0, 0);
- child.setLayoutParams(layout);
+ lparams.setMargins(0, 0, 0, 0);
+
+ if (child.getId() == R.id.navigation_bar_container) {
+ lparams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+ lparams.removeRule(RelativeLayout.BELOW);
+ } else if (child.getId() == R.id.icon_container) {
+ int top = (int) child.getResources()
+ .getDimension(R.dimen.collapsed_icon_card_margin_top);
+ lparams.setMargins(0, top, 0, 0);
+ }
+
+ child.getLayoutParams();
+ child.collapse();
}
mPreviewContent.requestLayout();
-
- animateChildren(false);
+ animateChildren(false, getChildrensGlobalBounds());
animateWallpaperIn();
}
- // This will animate the children's vertical value between the existing and
- // new layout changes
- private void animateChildren(final boolean isExpanding) {
+ // This will animate the children's vertical positions between the previous bounds and the
+ // new bounds which occur on the next draw
+ private void animateChildren(final boolean isExpanding, final List<Rect> prevBounds) {
final ViewGroup root = (ViewGroup) getActivity().getWindow()
.getDecorView().findViewById(android.R.id.content);
- // Get the child's current location
- final List<Float> prevYs = new ArrayList<Float>();
- for (int i = 0; i < mPreviewContent.getChildCount(); i++) {
- final View v = mPreviewContent.getChildAt(i);
- int[] pos = new int[2];
- v.getLocationInWindow(pos);
- prevYs.add((float) pos[1]);
- }
-
// Grab the child's new location and animate from prev to current loc.
final ViewTreeObserver observer = mScrollContent.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@@ -241,22 +284,28 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
observer.removeOnPreDrawListener(this);
for (int i = mPreviewContent.getChildCount() - 1; i >= 0; i--) {
- final View v = mPreviewContent.getChildAt(i);
+ final ComponentCardView v = (ComponentCardView) mPreviewContent.getChildAt(i);
- float prevY;
- float endY;
- if (i >= prevYs.size()) {
+ float prevY; float endY;
+ float prevHeight; float endHeight;
+ if (i >= prevBounds.size()) {
// View is being created
prevY = mPreviewContent.getTop() + mPreviewContent.getHeight();
endY = v.getY();
+ prevHeight = v.getHeight();
+ endHeight = v.getHeight();
} else {
- prevY = prevYs.get(i);
+ Rect boundary = prevBounds.get(i);
+ prevY = boundary.top;
+ prevHeight = boundary.height();
+
int[] endPos = new int[2];
v.getLocationInWindow(endPos);
endY = endPos[1];
+ endHeight = v.getHeight();
}
- v.setTranslationY((prevY - endY));
+ v.setTranslationY((prevY - endY) + (prevHeight - endHeight) / 2);
root.getOverlay().add(v);
// Expanding has a delay while the wallpaper begins to fade out
@@ -275,6 +324,13 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
mPreviewContent.addView(v, 0);
}
});
+ v.postDelayed(new Runnable() {
+ public void run() {
+ if (isExpanding) {
+ v.animateExpand();
+ }
+ }
+ }, ANIMATE_DURATION / 2);
}
@@ -313,16 +369,11 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
}
private void animateWallpaperIn() {
+ mWallpaper.setVisibility(View.VISIBLE);
mWallpaper.setTranslationY(0);
mWallpaper.animate()
- .setStartDelay(ANIMATE_START_DELAY)
.alpha(1f)
- .setDuration(300)
- .withEndAction(new Runnable() {
- public void run() {
- mWallpaper.setVisibility(View.VISIBLE);
- }
- });
+ .setDuration(300);
}
private String getAppliedFontPackageName() {
@@ -394,6 +445,7 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
c.moveToFirst();
+ if (c.getCount() == 0) return;
loadWallpaper(c);
loadStatusBar(c);
loadIcons(c);
@@ -462,7 +514,7 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
// fall back to the default icon set
IconPreviewHelper helper = new IconPreviewHelper(getActivity(), "");
for(int i=0; i < mIconContainer.getChildCount() && i < iconIdx.length; i++) {
- ImageView v = (ImageView) mIconContainer.getChildAt(i);
+ ImageView v = (ImageView) ((ViewGroup)mIconContainer.getChildAt(1)).getChildAt(i);
Bitmap bitmap = Utils.loadBitmapBlob(c, iconIdx[i]);
if (bitmap == null) {
ComponentName component = sIconComponents[i];