summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClark Scheff <clark@cyngn.com>2014-07-16 16:53:08 -0700
committerd34d <clark@cyngn.com>2014-07-17 08:29:28 -0700
commitaccf71cc2f859c8c8d241e7f67fe118ac82bf6f5 (patch)
treef65476e4165b18d419e29ae6bab7b22bd0ccc893
parente8e880c66ba2734cf1f5101ca2d3f19658b55bf0 (diff)
downloadpackages_apps_ThemeChooser-accf71cc2f859c8c8d241e7f67fe118ac82bf6f5.zip
packages_apps_ThemeChooser-accf71cc2f859c8c8d241e7f67fe118ac82bf6f5.tar.gz
packages_apps_ThemeChooser-accf71cc2f859c8c8d241e7f67fe118ac82bf6f5.tar.bz2
Add applying theme progress along with animations.
Change-Id: Id7835d3be0b9d9c8d861e820e63b45e17235ef68
-rw-r--r--AndroidManifest.xml1
-rw-r--r--res/drawable/apply_progress_background.xml8
-rw-r--r--res/drawable/apply_progress_bar.xml12
-rw-r--r--res/drawable/apply_progress_indicator.xml8
-rw-r--r--res/layout/v2_fragment_pager_list.xml67
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/dimens.xml1
-rw-r--r--src/android/support/v4/view/ThemeViewPager.java2
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java23
-rw-r--r--src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java133
10 files changed, 218 insertions, 40 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 92cd060..c11a5a9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -44,6 +44,7 @@
<activity android:name="org.cyanogenmod.theme.chooserv2.ChooserActivity"
android:label="@string/app_name"
android:theme="@style/ThemeChooserV2Theme"
+ android:configChanges="themeChange"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
diff --git a/res/drawable/apply_progress_background.xml b/res/drawable/apply_progress_background.xml
new file mode 100644
index 0000000..47c2530
--- /dev/null
+++ b/res/drawable/apply_progress_background.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+
+ <solid android:color="@color/apply_progress_background_color" />
+
+</shape> \ No newline at end of file
diff --git a/res/drawable/apply_progress_bar.xml b/res/drawable/apply_progress_bar.xml
new file mode 100644
index 0000000..a3cbc6f
--- /dev/null
+++ b/res/drawable/apply_progress_bar.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:id="@android:id/background"
+ android:drawable="@drawable/apply_progress_background"/>
+
+ <item android:id="@android:id/progress">
+ <clip android:drawable="@drawable/apply_progress_indicator"/>
+ </item>
+
+</layer-list> \ No newline at end of file
diff --git a/res/drawable/apply_progress_indicator.xml b/res/drawable/apply_progress_indicator.xml
new file mode 100644
index 0000000..0f332ed
--- /dev/null
+++ b/res/drawable/apply_progress_indicator.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+
+ <solid android:color="@color/apply_progress_color" />
+
+</shape> \ No newline at end of file
diff --git a/res/layout/v2_fragment_pager_list.xml b/res/layout/v2_fragment_pager_list.xml
index 70c1b3c..fc3c26e 100644
--- a/res/layout/v2_fragment_pager_list.xml
+++ b/res/layout/v2_fragment_pager_list.xml
@@ -40,39 +40,56 @@
<include layout="@layout/v2_nav_bar_preview_item"/>
</RelativeLayout>
</FrameLayout>
- <RelativeLayout
+ <FrameLayout
android:id="@+id/title_card"
- android:layout_below="@id/shadow_frame"
android:layout_width="@dimen/theme_preview_width"
android:layout_height="48dp"
+ android:layout_below="@id/shadow_frame"
android:layout_centerHorizontal="true"
android:background="@drawable/card_themepreview_bg">
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:layout_marginStart="16dp"
- android:gravity="center"
- android:ellipsize="end"
- android:textColor="#78000000"/>
+ <RelativeLayout
+ android:id="@+id/title_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentLeft="true"
+ android:layout_marginStart="16dp"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:textColor="#78000000"/>
- <ImageView
- android:id="@+id/apply"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toLeftOf="@+id/overflow"
- android:layout_marginRight="16dp"
- android:src="@drawable/ic_theme_apply2"/>
+ <ImageView
+ android:id="@+id/apply"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_toLeftOf="@+id/overflow"
+ android:layout_marginRight="16dp"
+ android:src="@drawable/ic_theme_apply2"/>
- <ImageView
- android:id="@+id/overflow"
- android:layout_width="wrap_content"
+ <ImageView
+ android:id="@+id/overflow"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="8dp"
+ android:src="@drawable/ic_overflow_dark"/>
+ </RelativeLayout>
+ <ProgressBar
+ android:id="@+id/apply_progress"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_marginRight="8dp"
- android:src="@drawable/ic_overflow_dark"/>
- </RelativeLayout>
+ android:layout_gravity="center_vertical|right"
+ android:padding="@dimen/apply_progress_padding"
+ android:indeterminate="false"
+ android:max="100"
+ android:progress="0"
+ android:progressDrawable="@drawable/apply_progress_bar"
+ android:visibility="gone"
+ style="@android:style/Widget.ProgressBar.Horizontal"/>
+ </FrameLayout>
</RelativeLayout>
</ScrollView>
</LinearLayout> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index c25d282..cdc1eca 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -41,4 +41,7 @@
<drawable name="save_apply_button_normal">#cd00b3e6</drawable>
<drawable name="save_apply_button_focused">#cd1fcdff</drawable>
<drawable name="save_apply_button_pressed">#cd0093bd</drawable>
+
+ <color name="apply_progress_background_color">#e0dfe1</color>
+ <color name="apply_progress_color">#00b3e6</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a6586ed..346c22f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -65,4 +65,5 @@
<dimen name="icon_component_margin">4dp</dimen>
<dimen name="content_offset_padding">10dp</dimen>
+ <dimen name="apply_progress_padding">10dp</dimen>
</resources>
diff --git a/src/android/support/v4/view/ThemeViewPager.java b/src/android/support/v4/view/ThemeViewPager.java
index 9a4ce9d..cf13871 100644
--- a/src/android/support/v4/view/ThemeViewPager.java
+++ b/src/android/support/v4/view/ThemeViewPager.java
@@ -49,7 +49,7 @@ public class ThemeViewPager extends ViewPager {
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = false;
- if (!mExpanded) {
+ if (!mExpanded && isEnabled()) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercept = !isTouchingApplyButton(ev);
diff --git a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java b/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
index 72b936e..3c4adca 100644
--- a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
+++ b/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java
@@ -35,19 +35,15 @@ import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
-import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
-import android.widget.TextView;
import org.cyanogenmod.theme.chooser.R;
import org.cyanogenmod.theme.chooserv2.ComponentSelector.OnOpenCloseListener;
import org.cyanogenmod.theme.util.TypefaceHelperCache;
import org.cyanogenmod.theme.util.Utils;
-import java.util.Map;
-
import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ALARMS;
import static android.provider.ThemesContract.ThemesColumns.MODIFIES_BOOT_ANIM;
import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NOTIFICATIONS;
@@ -156,6 +152,25 @@ public class ChooserActivity extends FragmentActivity
});
}
+ /**
+ * Disable the ViewPager while a theme change is occuring
+ */
+ public void themeChangeStarted() {
+ mPager.setEnabled(false);
+ }
+
+ /**
+ * Re-enable the ViewPager and update the "My theme" fragment if available
+ */
+ public void themeChangeEnded() {
+ ThemeFragment f = (ThemeFragment) getSupportFragmentManager()
+ .findFragmentByTag(getFragmentTag(0));
+ if (f != null) {
+ f.clearChanges();
+ mPager.setEnabled(true);
+ }
+ }
+
public ComponentSelector getComponentSelector() {
return mSelector;
}
diff --git a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java b/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
index 26fad1b..cf0202d 100644
--- a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
+++ b/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java
@@ -48,9 +48,13 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
+import android.view.animation.ScaleAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -71,12 +75,17 @@ import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NAVIGATION_
import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ICONS;
import static android.provider.ThemesContract.ThemesColumns.MODIFIES_FONTS;
-public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
+public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>,
+ ThemeManager.ThemeChangeListener {
public static final int ANIMATE_START_DELAY = 200;
public static final int ANIMATE_DURATION = 300;
public static final int ANIMATE_INTERPOLATE_FACTOR = 3;
public static final int ANIMATE_COMPONENT_CHANGE_DURATION = 200;
public static final int ANIMATE_COMPONENT_ICON_DELAY = 50;
+ public static final int ANIMATE_PROGRESS_IN_DURATION = 500;
+ public static final int ANIMATE_TITLE_OUT_DURATION = 400;
+ public static final int ANIMATE_PROGRESS_OUT_DURATION = 400;
+ public static final int ANIMATE_TITLE_IN_DURATION = 500;
public static final String CURRENTLY_APPLIED_THEME = "currently_applied_theme";
@@ -142,9 +151,11 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
// Title Card Views
private ViewGroup mTitleCard;
+ private ViewGroup mTitleLayout;
private TextView mTitle;
private ImageView mApply;
private ImageView mOverflow;
+ private ProgressBar mProgress;
private Handler mHandler;
@@ -186,7 +197,7 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
mHandler = new Handler();
// populate mSelectedComponentsMap with supported components for this theme
- if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) {
+ if (!CURRENTLY_APPLIED_THEME.equals(mPkgName)) {
List<String> components = ThemeUtils.getSupportedComponents(getActivity(), mPkgName);
mSelectedComponentsMap = new HashMap<String, String>(components.size());
for (String component : components) {
@@ -229,19 +240,14 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
// Title Card
mTitleCard = (ViewGroup)v.findViewById(R.id.title_card);
+ mTitleLayout = (ViewGroup) v.findViewById(R.id.title_layout);
mTitle = (TextView) v.findViewById(R.id.title);
+ mProgress = (ProgressBar) v.findViewById(R.id.apply_progress);
mOverflow = (ImageView) v.findViewById(R.id.overflow);
mApply = (ImageView) v.findViewById(R.id.apply);
mApply.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- Context context = getActivity();
- if (context != null) {
- if (mSelectedComponentsMap != null && mSelectedComponentsMap.size() > 0) {
- ThemeManager mService =
- (ThemeManager) context.getSystemService(Context.THEME_SERVICE);
- mService.requestThemeChange(mSelectedComponentsMap);
- }
- }
+ applyTheme();
}
});
@@ -262,6 +268,28 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
}
}
+ @Override
+ public void onProgress(int progress) {
+ mProgress.setProgress(progress);
+ }
+
+ @Override
+ public void onFinish(boolean isSuccess) {
+ // We post a runnable to mHandler so the client is removed from the same thread
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ThemeManager tm = getThemeManager();
+ if (tm != null) tm.removeClient(ThemeFragment.this);
+ }
+ });
+ if (isSuccess) {
+ mProgress.setProgress(100);
+ animateProgressOut();
+ ((ChooserActivity) getActivity()).themeChangeEnded();
+ }
+ }
+
public void expand() {
// Full width and height!
ViewGroup content = (ViewGroup) mScrollView.getParent();
@@ -566,6 +594,14 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
ThemeConfig.getSystemTheme().getFontPkgName();
}
+ private ThemeManager getThemeManager() {
+ final Context context = getActivity();
+ if (context != null) {
+ return (ThemeManager) context.getSystemService(Context.THEME_SERVICE);
+ }
+ return null;
+ }
+
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String pkgName = mPkgName;
@@ -982,6 +1018,83 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb
.animateContentChange(viewToAnimate, overlay, ANIMATE_COMPONENT_CHANGE_DURATION);
}
+ private Runnable mApplyThemeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ final Context context = getActivity();
+ if (context != null) {
+ if (mSelectedComponentsMap != null && mSelectedComponentsMap.size() > 0) {
+ // Post this on mHandler so the client is added and removed from the same
+ // thread
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ThemeManager tm = getThemeManager();
+ if (tm != null) {
+ tm.addClient(ThemeFragment.this);
+ tm.requestThemeChange(mSelectedComponentsMap);
+ }
+ }
+ });
+ }
+ }
+ }
+ };
+
+ private void applyTheme() {
+ if (mSelectedComponentsMap == null || mSelectedComponentsMap.size() <= 0) return;
+ ((ChooserActivity) getActivity()).themeChangeStarted();
+ animateProgressIn(mApplyThemeRunnable);
+ }
+
+ private void animateProgressIn(Runnable endAction) {
+ mProgress.setVisibility(View.VISIBLE);
+ mProgress.setProgress(0);
+ float pivotX = mTitleLayout.getWidth() -
+ getResources().getDimensionPixelSize(R.dimen.apply_progress_padding);
+ ScaleAnimation scaleAnim = new ScaleAnimation(0f, 1f, 1f, 1f,
+ pivotX, 0f);
+ scaleAnim.setDuration(ANIMATE_PROGRESS_IN_DURATION);
+
+ mTitleLayout.animate()
+ .translationXBy(-(pivotX / 4))
+ .alpha(0f)
+ .setDuration(ANIMATE_TITLE_OUT_DURATION)
+ .setInterpolator(new AccelerateInterpolator())
+ .withEndAction(endAction).start();
+ mProgress.startAnimation(scaleAnim);
+ }
+
+ private void animateProgressOut() {
+ mProgress.setVisibility(View.VISIBLE);
+ float pivotX = mTitleLayout.getWidth() -
+ getResources().getDimensionPixelSize(R.dimen.apply_progress_padding);
+ ScaleAnimation scaleAnim = new ScaleAnimation(1f, 0f, 1f, 1f,
+ pivotX, 0f);
+ scaleAnim.setDuration(ANIMATE_PROGRESS_OUT_DURATION);
+ scaleAnim.setFillAfter(false);
+ scaleAnim.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {}
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ mProgress.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {}
+ });
+
+ mTitleLayout.animate()
+ .translationXBy((pivotX / 4))
+ .alpha(1f)
+ .setDuration(ANIMATE_TITLE_IN_DURATION)
+ .setInterpolator(new AccelerateInterpolator())
+ .start();
+ mProgress.startAnimation(scaleAnim);
+ }
+
public void fadeInCards() {
mActiveCardId = -1;
for (int i = 0; i < sCardIdsToComponentTypes.size(); i++) {