1616
1717package cn .refactor .multistatelayout ;
1818
19+ import android .animation .ObjectAnimator ;
1920import android .annotation .SuppressLint ;
2021import android .annotation .TargetApi ;
2122import android .content .Context ;
2627import android .util .AttributeSet ;
2728import android .view .LayoutInflater ;
2829import android .view .View ;
30+ import android .view .animation .AccelerateInterpolator ;
2931import android .widget .FrameLayout ;
3032
3133import java .lang .annotation .Retention ;
4042public class MultiStateLayout extends FrameLayout {
4143
4244 private static MultiStateConfiguration .Builder mCommonConfiguration ;
45+ private static final int DEFAULT_ANIM_DURATION = 400 ;
46+ private static final boolean DEFAULT_ANIM_ENABLE = true ;
47+
4348 private View mContentView ;
4449 private View mLoadingView ;
4550 private View mEmptyView ;
@@ -51,7 +56,10 @@ public class MultiStateLayout extends FrameLayout {
5156 private int mLoadingResId ;
5257 private int mNetworkErrorResId ;
5358
59+ private int mAnimDuration ;
60+ private boolean mAnimEnable ;
5461 private LayoutInflater mInflater ;
62+ private ObjectAnimator mAlphaAnimator ;
5563
5664 @ IntDef ({State .CONTENT , State .EMPTY , State .LOADING , State .ERROR , State .NETWORK_ERROR })
5765 @ Retention (RetentionPolicy .SOURCE )
@@ -86,10 +94,13 @@ public MultiStateLayout(Context context, AttributeSet attrs, int defStyleAttr, i
8694
8795 private void init (AttributeSet attrs ) {
8896 TypedArray ta = getContext ().obtainStyledAttributes (attrs , R .styleable .MultiStateLayout );
89- mEmptyResId = ta .getResourceId (R .styleable .MultiStateLayout_empty_layout , getCommonLayoutResIdByState (State .EMPTY ));
90- mErrorResId = ta .getResourceId (R .styleable .MultiStateLayout_error_layout , getCommonLayoutResIdByState (State .ERROR ));
91- mLoadingResId = ta .getResourceId (R .styleable .MultiStateLayout_loading_layout , getCommonLayoutResIdByState (State .LOADING ));
92- mNetworkErrorResId = ta .getResourceId (R .styleable .MultiStateLayout_network_error_layout , getCommonLayoutResIdByState (State .NETWORK_ERROR ));
97+ mEmptyResId = ta .getResourceId (R .styleable .MultiStateLayout_layout_empty , getCommonLayoutResIdByState (State .EMPTY ));
98+ mErrorResId = ta .getResourceId (R .styleable .MultiStateLayout_layout_error , getCommonLayoutResIdByState (State .ERROR ));
99+ mLoadingResId = ta .getResourceId (R .styleable .MultiStateLayout_layout_loading , getCommonLayoutResIdByState (State .LOADING ));
100+ mNetworkErrorResId = ta .getResourceId (R .styleable .MultiStateLayout_layout_network_error , getCommonLayoutResIdByState (State .NETWORK_ERROR ));
101+
102+ mAnimEnable = ta .getBoolean (R .styleable .MultiStateLayout_animEnable , DEFAULT_ANIM_ENABLE );
103+ mAnimDuration = ta .getInt (R .styleable .MultiStateLayout_animDuration , DEFAULT_ANIM_DURATION );
93104 ta .recycle ();
94105
95106 mInflater = LayoutInflater .from (getContext ());
@@ -108,6 +119,12 @@ protected void onFinishInflate() {
108119 }
109120 }
110121
122+ @ Override
123+ protected void onDetachedFromWindow () {
124+ super .onDetachedFromWindow ();
125+ clearTargetViewAnimation ();
126+ }
127+
111128 /**
112129 * set common mCommonConfiguration settings
113130 *
@@ -125,6 +142,7 @@ public static void setConfiguration(MultiStateConfiguration.Builder builder) {
125142 @ SuppressLint ("Assert" )
126143 public void setState (@ State int state ) {
127144 assert !(state < State .CONTENT || state > State .NETWORK_ERROR );
145+ clearTargetViewAnimation ();
128146 hideViewByState (mCurState );
129147 showViewByState (state );
130148 mCurState = state ;
@@ -306,6 +324,12 @@ public View getNetworkErrorView() {
306324 return mNetworkErrorView ;
307325 }
308326
327+ private void clearTargetViewAnimation () {
328+ if (null != mAlphaAnimator && mAlphaAnimator .isRunning ()) {
329+ mAlphaAnimator .cancel ();
330+ }
331+ }
332+
309333 private void hideViewByState (@ State int state ) {
310334 switch (state ) {
311335 case State .CONTENT :
@@ -366,7 +390,21 @@ private void showViewByState(@State int state) {
366390 }
367391
368392 /**
369- * show content view
393+ * start alpha animation
394+ * @param targetView target view
395+ */
396+ private void execAlphaAnimation (View targetView ) {
397+ if (null == targetView ) {
398+ return ;
399+ }
400+ mAlphaAnimator = ObjectAnimator .ofFloat (targetView , "alpha" , 0.0f , 1.0f );
401+ mAlphaAnimator .setInterpolator (new AccelerateInterpolator ());
402+ mAlphaAnimator .setDuration (mAnimDuration );
403+ mAlphaAnimator .start ();
404+ }
405+
406+ /**
407+ * show content view without animation
370408 */
371409 private void showContentView () {
372410 if (null != mContentView ) {
@@ -384,6 +422,9 @@ private void showEmptyView() {
384422 }
385423 if (null != mEmptyView ) {
386424 mEmptyView .setVisibility (VISIBLE );
425+ if (mAnimEnable ) {
426+ execAlphaAnimation (mEmptyView );
427+ }
387428 } else {
388429 throw new NullPointerException ("Expect to have an empty view." );
389430 }
@@ -399,6 +440,9 @@ private void showLoadingView() {
399440 }
400441 if (null != mLoadingView ) {
401442 mLoadingView .setVisibility (VISIBLE );
443+ if (mAnimEnable ) {
444+ execAlphaAnimation (mLoadingView );
445+ }
402446 } else {
403447 throw new NullPointerException ("Expect to have an loading view." );
404448 }
@@ -414,6 +458,9 @@ private void showErrorView() {
414458 }
415459 if (null != mErrorView ) {
416460 mErrorView .setVisibility (VISIBLE );
461+ if (mAnimEnable ) {
462+ execAlphaAnimation (mErrorView );
463+ }
417464 } else {
418465 throw new NullPointerException ("Expect to have one error view." );
419466 }
@@ -429,6 +476,9 @@ private void showNetworkErrorView() {
429476 }
430477 if (null != mNetworkErrorView ) {
431478 mNetworkErrorView .setVisibility (VISIBLE );
479+ if (mAnimEnable ) {
480+ execAlphaAnimation (mNetworkErrorView );
481+ }
432482 } else {
433483 throw new NullPointerException ("Expect to have one network error view." );
434484 }
0 commit comments