From 2087d2d545fa57d870ea63e4df8d0176f809c1d8 Mon Sep 17 00:00:00 2001 From: Bartosz Przybylski Date: Thu, 26 Nov 2015 16:25:45 +0100 Subject: [PATCH] Add Whats new activity and embed it into project --- AndroidManifest.xml | 3 +- res/drawable-hdpi/ic_menu_forward.png | Bin 0 -> 977 bytes res/drawable-mdpi/ic_menu_forward.png | Bin 0 -> 769 bytes res/drawable-xhdpi/ic_menu_forward.png | Bin 0 -> 1227 bytes res/drawable-xxhdpi/ic_menu_forward.png | Bin 0 -> 1945 bytes res/drawable/indicator_dot_background.xml | 9 + res/drawable/indicator_dot_selected.xml | 9 + res/layout/whats_new_activity.xml | 59 +++++ res/layout/whats_new_element.xml | 30 +++ res/values/strings.xml | 18 ++ src/com/owncloud/android/MainApp.java | 2 + .../android/ui/activity/WhatsNewActivity.java | 219 ++++++++++++++++++ .../ui/whatsnew/ProgressIndicator.java | 128 ++++++++++ 13 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 res/drawable-hdpi/ic_menu_forward.png create mode 100644 res/drawable-mdpi/ic_menu_forward.png create mode 100644 res/drawable-xhdpi/ic_menu_forward.png create mode 100644 res/drawable-xxhdpi/ic_menu_forward.png create mode 100644 res/drawable/indicator_dot_background.xml create mode 100644 res/drawable/indicator_dot_selected.xml create mode 100644 res/layout/whats_new_activity.xml create mode 100644 res/layout/whats_new_element.xml create mode 100644 src/com/owncloud/android/ui/activity/WhatsNewActivity.java create mode 100644 src/com/owncloud/android/ui/whatsnew/ProgressIndicator.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 373e32eebb..53e5282a27 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -219,7 +219,8 @@ - + + diff --git a/res/drawable-hdpi/ic_menu_forward.png b/res/drawable-hdpi/ic_menu_forward.png new file mode 100644 index 0000000000000000000000000000000000000000..b1b0c89d5c891af9d800cef0ed9b4e2f52bb6af1 GIT binary patch literal 977 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;XrLSJzX3_A`ZWu?&~k?C~^G%`MmP&`L~@eZewbj z7Sz+pc|`kaMw4Jrp4=avCF=HFoLZlFeH`-S9=zbLSlY=Mvqn6MU&Kkf_V(Q4%}aw! zO4uGI95OyRudIIm%;z&_&ShNp=s!18tlq!xpBEiw;OJ<}yTNcG;MGKteXa?`i)J!L zzn89@&@S8g-lnL6o0q9t{nh33lXP`{G_80htJ$ijUci~-XR@rg^ZB)&xJ~A4Z?Zn` zR^UI<%E2**=iS+-$HaBQ1E0(RN5?x!jFbG^Yc#4bl;7^ge zOigT7t2vXB&feYpy`0U=Idb#%M_)L0luJKy&U$mSY=4Wr`=)8SM`m`tJFC~=D3Q>a zBN&yo$+9Xx$5KXA&m^sO-@cFy*R?7q99(P9!s5o@zlOzA-*(HHYYV>`>|52U=#cAL zuyz*v&z~#)-a2{L zMx&tOf|LGh&hbw1E?66oaI%%HMD$|?3y*_=_=V*wmu1ZORnI8# ztEP5iLY+?8uluphlRm%ITq*X`@sIAp*e5Zy8wDc%Z!Fz(;=h^iQ&s_PXOaGbGlKGAH zwW}V)z5LkVDc*SH-{Uhky7X@eub-jBKcj?i$+vXlm!kW5;yerF_8f9DKHoZBu90zW z$J#56N^y3sEZ>%9ovQdL@-cRGS$$PasGz>KLc;xq@6*b9Wiz-cS|{Iiyj)=R`*hj0 zgj1#|A1^U+>vc}r{!KH8b8m6{w(TY}AMbv}nzG4~)y&>R^`qBAMvfhFecG`LLmnIH zH_9Ge`e^;5M~~IL|NN`J^zZ0nV2W2Qag8WRNi0dVN-jzTQVd20hK9NZhPp-;Ax1`4 zCgxVA#<~U;Rt5%3{EAMZXvob^$xN%nt>LQhsZyW@NstY}`DrEPiAAXljw$&`sS2LC ciRr09sfj6-g(p*OfQlGAUHx3vIVCg!0C&otrvLx| literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/ic_menu_forward.png b/res/drawable-mdpi/ic_menu_forward.png new file mode 100644 index 0000000000000000000000000000000000000000..4a0b6ef68b4dd16bca545dd14b227fdd61d64651 GIT binary patch literal 769 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE>Ih%r;B5V$MK_6ef@<4McVEcr~h&_4e(B~Z_Dys zBdO@7V7P1Hj>2S~+?c7GKJjn(n(y(*ZJWg1jA)OJ&iaEbtnW$`4L4|Ux3~Ds-1&W% z#?~9>_AVB9yt8}e(aQOj^7+r0{#*B4;3*TdY4n@_eC2^9hM8`EgIc=#q!u!A94L?v z&+2jBaVc2G<-p)7Y(D+ifz^-B`owewY6ZkJ-%@vFIf97gUsNh>elCt~jN^*5_bihV}2NBMc6Qk1MieE_f@Gb6>+h zWvA|PnvN`ev$>kJz*SY`d)Y=eJ zYvbY+-R+w`%V~J5yXho(pOZ;-^}SQ)f2LRc_gy!e(Q(m~)%lrEcgc6Tm~8yA&fxjW zCs_?FPduNWerCus*G5H&P3!9PYg(5q&i_pa66(~rYZlD$wYzGhU$XQ|snJ5^pbI9#duJLfPT0l4yy{N>efw{U zoCYjTr=)`nVwgW_{0L6DzR2wrGlzjpGFKamQb*a9z{}Ye!+yz}Xlh!>$i|%)7@Zof zt0`fwWH9jt=UUAf(hSF(4xTz-p>ab}f|)g&d7H=^-iRQHv<3wS<=BP~QUBIi?G(#h z>bBTm4nu!k>jA#M57WY2ZEd+&Do3Pm|563!$BI3e*LwM(`AXJ% z4Nd{FW~RJVU5{lxbx7*5HSxQ(ym9)*w%k!6!{X26m^V4s_QvlH{o!&a-SOMsxqE}m z>$iQl7jhu&uo5@hf-md#sT(CM=x=g~uzk1vmj;i-gp=#4lnZ-x*mG}Aeqnp0aas7G z^_Rq7=vm&`)wy4lp+WLPWOL%v#^3E{1%dhJ`i=i;K#N-7jFK!yL0#TH-b`W4UHcZo8Eu7+Zx;QP%lQ^DZcfmz2BZ~ zThn^~?1!-Vd+XDs{pQ)I5Bkky%+^U2d z0aY`S;xE0n+8+|p*nB)UJvJ`ue&&k$9P7u54h>!})8kIWOy|q){?hPqx?pBV+0}1X zb_W$YbX|XX^qZUW)jxtyd;2qD*3M4+c0A+vjo+7^&VTBZzWAZ!32EUAD)I%ve*XpD zsu)*e zS3LTD;#J2}b<>sqt8JOs)VI5uU0w7Yn9o&9Tq8Y7~lA?MB6RI@TZkW_G{pd7k(9-gjmE zjA(z~_k95X{;@Gw0zEHqe=KkM-?K4CLQlbzI*Cdo)2ST24F?J%nTA8L7QG2i!1c!5 z#qIbM06f#px+E$|J6&cVEnK}D!*y7!G#h{^Q4Xu#kcm@J8g4QZk?h|Nx3D3zF_Jx7 zsD-sw6`o;^$+O{!c{6l|yi9}C$c~x{O>xL*0Siv)A%|rVVV5}~*)Mfv^xA#QV?!?? zRAwaml~YODct}Osa7f67BMh(zhC~P#;S0oKaX5s+2+V^~9)d<7Vi_Nm!7%iCuxV>H zW4bH>)4aAt?;_b56lIn1csV&a+#Eiaw3&E_R4R3AplAe*h_L4pl-?0R*vAhkV7T32 zGg~P$NkDEzeHxiXMY3s6Uxi??YPD~K3H$3r(JA9O^j03ig?Sc>JFb^#JC%U{?Z#Wt zc3rL&=Oy5FGRtP5-y?ne5Sh;1yA8R4v^TPuHZ%Pw`b8LN$g z1V#|C02ZULNP^Je3sh1es=)Xvp+cz?4r#oNi>gIZm`^kLA`C&)uo4ld6cPcZkzg8; zQpz9V#u9c)PZ;nayJp(%Yp&>>T$##->nYNvBgsWW6%e06QlveDv_h&xA*9tC%!GUI zex6s+Vz|wmjT<#K(gMBAugv@w`(m{am8b<84fbDgzv3GIPtJI>Gdy>3{G(Wgj_3+> zFW;0ty?N6-I6-%ejc$!Qd!1wHj%$y_6gtO`cWcjO1}R2;Yf=f2<}ZECjd#?0N_w1u z!`8(tpT~)i_E#2gUPMDuul5}!&^l&uN$1?wRhft)YWr=0K>1Us6XPQ3zlbJW|!J?ikp-$w?=%3a%Z>YZ{A@Zwxe4Jj+^}8-FmOm~{ z34!&`k92o;M|X8~RhXY1l{TyEa@n<3__itYQ1wDlO&Qc!uP80r)FS=vPmH~-s(r$Q zWn(G_e>`rEDx{N=*0Yc zl&qnfNL`ZS&G2A=@?Ia^XPq@mkNtG-?Ag@|56uaOpz`9Bn%))XHbbpo>ny9rIf)3^ zdf!u`EIb@^+uOs&Ee&E`@e1Y!Y@OXEkr$>`VI{3;+A+b58g;IY)!4)i2;CPKr&!vG z@>s(dU2Wl`SdILf0nomg+IbXf%_;x+M%MbZ9nJg0;acXQubwyl!0z>S3d`mi?|T~V ze^G#)Usu#$lzn5o1Xjm)>c(+OX`sqLDwDy7S~<9 z(Em|b;x1j&a%GV=YR$AA>C1(`2C+U|gXe){;|RaPRfCm4vT1}*Va;GX zkW^P(Vr;SVL%c!lv%KI3&DU=krzZHF+GzWv?%eL=rlye{(G2Ut)2n9f&YH#D@Pk#d zOiW{gcc#V`WMtpC-1qo}QjUf+1c^vh0e`r@px_0Mm2tb`iTL2bQ4LG;ImU~3S6{E+ zoqDUGZ{&(WBC@E%59K{LTduk@@O0be!8J_S>v-9d$DYG~QKV)oeFB + + + + diff --git a/res/drawable/indicator_dot_selected.xml b/res/drawable/indicator_dot_selected.xml new file mode 100644 index 0000000000..684ca90fd7 --- /dev/null +++ b/res/drawable/indicator_dot_selected.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/res/layout/whats_new_activity.xml b/res/layout/whats_new_activity.xml new file mode 100644 index 0000000000..a78f2dd2a7 --- /dev/null +++ b/res/layout/whats_new_activity.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/whats_new_element.xml b/res/layout/whats_new_element.xml new file mode 100644 index 0000000000..025647bec1 --- /dev/null +++ b/res/layout/whats_new_element.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 359597a328..4776629129 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -545,4 +545,22 @@ SD card %1$d Unknown + + Welcome to nextCloud! + What\'s new in nextCloud + + + Instant upload + Keep your photos safe + + Manage all your files + You can delete, move + + Share + You can share files and folders + + MultiAccount + Connect to all your clouds + + Your private files synced anywhere diff --git a/src/com/owncloud/android/MainApp.java b/src/com/owncloud/android/MainApp.java index 56345e7c8d..0fc13a2d10 100644 --- a/src/com/owncloud/android/MainApp.java +++ b/src/com/owncloud/android/MainApp.java @@ -41,6 +41,7 @@ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.services.observer.SyncedFolderObserverService; import com.owncloud.android.ui.activity.Preferences; +import com.owncloud.android.ui.activity.WhatsNewActivity; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -118,6 +119,7 @@ public class MainApp extends Application { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log_OC.d(activity.getClass().getSimpleName(), "onCreate(Bundle) starting" ); + WhatsNewActivity.runIfNeeded(activity); PassCodeManager.getPassCodeManager().onActivityCreated(activity); } diff --git a/src/com/owncloud/android/ui/activity/WhatsNewActivity.java b/src/com/owncloud/android/ui/activity/WhatsNewActivity.java new file mode 100644 index 0000000000..50d6b88d60 --- /dev/null +++ b/src/com/owncloud/android/ui/activity/WhatsNewActivity.java @@ -0,0 +1,219 @@ +/** + * ownCloud Android client application + * + * @author Bartosz Przybylski + * Copyright (C) 2015 Bartosz Przybylski + * Copyright (C) 2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.ui.activity; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.owncloud.android.BuildConfig; +import com.owncloud.android.MainApp; +import com.owncloud.android.R; +import com.owncloud.android.ui.whatsnew.ProgressIndicator; +import com.owncloud.android.lib.common.utils.Log_OC; + +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author Bartosz Przybylski + */ +public class WhatsNewActivity extends Activity { + private static String TAG = WhatsNewActivity.class.getSimpleName(); + + private static final String KEY_LAST_SEEN_VERSION_CODE = "lastSeenVersionCode"; + + private FeatureItem[] mFeaturesToShow; + + private ImageButton mForwardFinishButton; + private ProgressIndicator mProgress; + private LinearLayout mContentPanel; + + int currentStep = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.whats_new_activity); + mProgress = (ProgressIndicator) findViewById(R.id.progressIndicator); + mFeaturesToShow = filterFeaturesToShow(); + mProgress.setNumberOfSteps(mFeaturesToShow.length); + mForwardFinishButton = (ImageButton) findViewById(R.id.forward); + mForwardFinishButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mProgress.hasNextStep()) { + mProgress.animateToNextStep(); + mContentPanel.animate().x(-mContentPanel.getChildAt(++currentStep).getLeft()); + } else { + onFinish(); + finish(); + } + if (!mProgress.hasNextStep()) { + mForwardFinishButton.setImageResource(R.drawable.ic_ok); + } + } + }); + Button skipButton = (Button) findViewById(R.id.skip); + skipButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onFinish(); + finish(); + } + }); + + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); + final int lastSeenVersionCode = pref.getInt(KEY_LAST_SEEN_VERSION_CODE, 0); + final boolean isFirstRun = lastSeenVersionCode == 0; + TextView tv = (TextView)findViewById(R.id.welcomeText); + tv.setText(isFirstRun ? R.string.welcome_to_oc_title : R.string.whats_new_title); + + DisplayMetrics dm = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(dm); + + mContentPanel = (LinearLayout)findViewById(R.id.contentPanel); + LinearLayout.LayoutParams ll2 = (LinearLayout.LayoutParams) mContentPanel.getLayoutParams(); + ll2.width = dm.widthPixels*mFeaturesToShow.length; + mContentPanel.setLayoutParams(ll2); + LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); + + + for (int i = 0; i < mFeaturesToShow.length; ++i) { + FeatureItem item = mFeaturesToShow[i]; + LinearLayout newElement = (LinearLayout)inflater.inflate(R.layout.whats_new_element, null); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dm.widthPixels, ViewGroup.LayoutParams.MATCH_PARENT); + newElement.setLayoutParams(params); + + mContentPanel.addView(newElement); + ImageView iv = (ImageView)newElement.findViewById(R.id.whatsNewImage); + if (item.getImage() != FeatureItem.doNotShow) + iv.setImageResource(item.getImage()); + + TextView tv2 = (TextView)newElement.findViewById(R.id.whatsNewTitle); + if (item.getTitleText() != FeatureItem.doNotShow) + tv2.setText(item.getTitleText()); + + tv2 = (TextView)newElement.findViewById(R.id.whatsNewText); + if (item.getContentText() != FeatureItem.doNotShow) + tv2.setText(item.getContentText()); + } + } + + private void onFinish() { + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = pref.edit(); + editor.putInt(KEY_LAST_SEEN_VERSION_CODE, BuildConfig.VERSION_CODE); + editor.apply(); + } + + static public void runIfNeeded(Context context) { + if (context instanceof WhatsNewActivity) + return; + + if (filterFeaturesToShow().length > 0) + context.startActivity(new Intent(context, WhatsNewActivity.class)); + } + + static private FeatureItem[] filterFeaturesToShow() { + List features = new LinkedList<>(); + + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(MainApp.getAppContext()); + final int lastSeenVersionCode = pref.getInt(KEY_LAST_SEEN_VERSION_CODE, 0); + final boolean isFirstRun = lastSeenVersionCode == 0; + + for (FeatureItem item : featuresToShow) { + if (isFirstRun && item.shouldShowOnFirstRun()) { + features.add(item); + } else if (!isFirstRun && !item.shouldShowOnFirstRun() && + BuildConfig.VERSION_CODE >= item.getVersionNumber() && + lastSeenVersionCode < item.getVersionNumber()) { + features.add(item); + } + } + return features.toArray(new FeatureItem[features.size()]); + } + + static FeatureItem featuresToShow[] = { + new FeatureItem(R.drawable.logo, R.string.welcome_feature_1_title, R.string.welcome_feature_1_text, "1.0.0", true), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_2_title, R.string.welcome_feature_2_text, "1.0.0", true), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_3_title, R.string.welcome_feature_3_text, "1.0.0", true), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_4_title, R.string.welcome_feature_4_text, "1.0.0", true), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_5_title, FeatureItem.doNotShow, "1.0.0", true), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_1_title, FeatureItem.doNotShow, "1.8.3"), + new FeatureItem(R.drawable.logo, R.string.welcome_feature_2_title, FeatureItem.doNotShow, "1.8.4"), + }; + + static private class FeatureItem { + static final int doNotShow = -1; + private int image; + private int titleText; + private int contentText; + private int versionNumber; + private boolean showOnInitialRun; + + public FeatureItem(int image, int titleText, int contentText, String version) { + this(image, titleText, contentText, version, false); + } + + public FeatureItem(int image, int titleText, int contentText, String version, boolean showOnInitialRun) { + this.image = image; + this.titleText = titleText; + this.contentText = contentText; + this.versionNumber = versionCodeFromString(version); + this.showOnInitialRun = showOnInitialRun; + } + + public int getImage() { return image; } + public int getTitleText() { return titleText; } + public int getContentText() { return contentText; } + public int getVersionNumber() { return versionNumber; } + public boolean shouldShowOnFirstRun() { return showOnInitialRun; } + } + + static int versionCodeFromString(String version) { + String v[] = version.split(Pattern.quote(".")); + if (v.length != 3) { + Log_OC.wtf(TAG, "Version string is incorrect " + version); + return 0; + } + int result = Integer.parseInt(v[0])*(int)(10e6) + + Integer.parseInt(v[1])*(int)(10e4) + + Integer.parseInt(v[2]); + + return result; + } +} diff --git a/src/com/owncloud/android/ui/whatsnew/ProgressIndicator.java b/src/com/owncloud/android/ui/whatsnew/ProgressIndicator.java new file mode 100644 index 0000000000..c7bf52abd1 --- /dev/null +++ b/src/com/owncloud/android/ui/whatsnew/ProgressIndicator.java @@ -0,0 +1,128 @@ +/** + * ownCloud Android client application + * + * @author Bartosz Przybylski + * Copyright (C) 2015 Bartosz Przybylski + * Copyright (C) 2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.ui.whatsnew; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import com.owncloud.android.R; + +/** + * @author Bartosz Przybylski + */ +public class ProgressIndicator extends FrameLayout { + + protected LinearLayout mDotsContainer; + protected ImageView mCurrentProgressDot; + + protected int mNumberOfSteps; + protected int mCurrentStep; + + public ProgressIndicator(Context context) { + super(context); + setup(); + } + + public ProgressIndicator(Context context, AttributeSet attrs) { + super(context, attrs); + setup(); + } + + public ProgressIndicator(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setup(); + } + + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + // This is not the best place to reset steps but I couldn't find a better one + resetStep(); + } + + public boolean hasNextStep() { + return mNumberOfSteps > mCurrentStep; + } + + public void animateToNextStep() { + animateToStep(++mCurrentStep); + } + + public void resetStep() { + setStep(1); + } + + public void setNumberOfSteps(int steps) { + mNumberOfSteps = steps; + mDotsContainer.removeAllViews(); + for (int i = 0; i < steps; ++i) { + ImageView iv = new ImageView(getContext()); + iv.setImageDrawable(getContext().getResources().getDrawable(R.drawable.indicator_dot_background)); + mDotsContainer.addView(iv); + } + } + + private void setStep(int step) { + if (step < 1 || step > mNumberOfSteps) return; + + View dot = mDotsContainer.getChildAt(step-1); + FrameLayout.LayoutParams lp = (LayoutParams) mCurrentProgressDot.getLayoutParams(); + lp.leftMargin = dot.getLeft(); + lp.topMargin = dot.getTop(); + } + + private void animateToStep(int step) { + if (step < 1 || step > mNumberOfSteps) return; + View dot = mDotsContainer.getChildAt(step-1); + mCurrentProgressDot + .animate() + .x(dot.getLeft()) + .y(dot.getTop()); + } + + private void setup() { + mCurrentStep = 1; + + mDotsContainer = new LinearLayout(getContext()); + mDotsContainer.setGravity(Gravity.CENTER); + FrameLayout.LayoutParams params = generateDefaultLayoutParams(); + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + mDotsContainer.setLayoutParams(params); + addView(mDotsContainer); + + mCurrentProgressDot = new ImageView(getContext()); + params = generateDefaultLayoutParams(); + params.width = ViewGroup.LayoutParams.WRAP_CONTENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + mCurrentProgressDot.setLayoutParams(params); + mCurrentProgressDot.setImageDrawable(getContext().getResources().getDrawable(R.drawable.indicator_dot_selected)); + addView(mCurrentProgressDot); + } + +}