diff options
author | Clark Scheff <clark@cyngn.com> | 2014-07-16 16:53:08 -0700 |
---|---|---|
committer | d34d <clark@cyngn.com> | 2014-07-17 08:29:28 -0700 |
commit | accf71cc2f859c8c8d241e7f67fe118ac82bf6f5 (patch) | |
tree | f65476e4165b18d419e29ae6bab7b22bd0ccc893 | |
parent | e8e880c66ba2734cf1f5101ca2d3f19658b55bf0 (diff) | |
download | packages_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.xml | 1 | ||||
-rw-r--r-- | res/drawable/apply_progress_background.xml | 8 | ||||
-rw-r--r-- | res/drawable/apply_progress_bar.xml | 12 | ||||
-rw-r--r-- | res/drawable/apply_progress_indicator.xml | 8 | ||||
-rw-r--r-- | res/layout/v2_fragment_pager_list.xml | 67 | ||||
-rw-r--r-- | res/values/colors.xml | 3 | ||||
-rw-r--r-- | res/values/dimens.xml | 1 | ||||
-rw-r--r-- | src/android/support/v4/view/ThemeViewPager.java | 2 | ||||
-rw-r--r-- | src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java | 23 | ||||
-rw-r--r-- | src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java | 133 |
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++) { |