浅談activity状態layout

18104 ワード

一、カスタムstatusLayout
package com.xiaobai.mizar.android.ui.view;

import android.content.Context;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.base.platform.utils.android.ToastTool;
import com.xiaobai.mizar.utils.Common;
import com.xiaobai.mizar.utils.Logger;
import com.base.view.RotateLoading;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.xiaobai.mizar.R;
import com.xiaobai.mizar.logic.uimodels.mine.ActStatusModel;
import com.xiaobai.mizar.utils.TaskHandler;
import java.util.ArrayList;
import java.util.List;

/**
 * Author: walid
 * Date : 2015/11/2 11:12
 */

public class ActivityStatusLayout extends RelativeLayout {

   private static final String TAG_LOADING = "ActivityStatusLayout.TAG_LOADING";
   private static final String TAG_EMPTY = "ActivityStatusLayout.TAG_EMPTY";
   private static final String TAG_ERROR = "ActivityStatusLayout.TAG_ERROR";

   private final String CONTENT = "CONTENT";
   private final String LOADING = "LOADING";
   private final String EMPTY = "EMPTY";
   private final String ERROR = "ERROR";

   private LayoutInflater inflater;
   private LayoutParams layoutParams;

   private List<View> contentViews = new ArrayList<>();

   @ViewInject(R.id.loadingStateRelativeLayout)
   private RelativeLayout loadingStateRelativeLayout;
   @ViewInject(R.id.loadingStateRotateLoading)
   private RotateLoading loadingStateRotateLoading;

   private View emptyView;
   @ViewInject(R.id.emptyStateRelativeLayout)
   private RelativeLayout emptyStateRelativeLayout;
   @ViewInject(R.id.emptyStateImageView)
   private XiaoBaiImageView emptyStateImageView;
   @ViewInject(R.id.emptyStateTitleTextView)
   private XiaobaiTextView emptyStateTitleTextView;
   @ViewInject(R.id.emptyStateContentTextView)
   private XiaobaiTextView emptyStateContentTextView;

   @ViewInject(R.id.errorStateRelativeLayout)
   private RelativeLayout errorStateRelativeLayout;
   @ViewInject(R.id.errorStateImageView)
   private XiaoBaiImageView errorStateImageView;
   @ViewInject(R.id.errorStateTitleTextView)
   private XiaobaiTextView errorStateTitleTextView;
   @ViewInject(R.id.errorStateContentTextView)
   private XiaobaiTextView errorStateContentTextView;

   private TimeOutHandler timeOutHandler = new TimeOutHandler(this);
   private String state = CONTENT;

   public ActivityStatusLayout(Context context) {
      super(context);
   }

   public ActivityStatusLayout(Context context, AttributeSet attrs) {
      super(context, attrs);
      init(attrs);
   }

   public ActivityStatusLayout(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      init(attrs);
   }

   private void init(AttributeSet attrs) {
      inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   }

   @Override
   public void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) {
      super.addView(child, index, params);
      if (child.getTag() == null || (!child.getTag().equals(TAG_LOADING) &&
                                     !child.getTag().equals(TAG_EMPTY) && !child.getTag().equals(TAG_ERROR))) {
         contentViews.add(child);
      }
   }

   /**
    *  
    */
   public void showContent(ActStatusModel contentModel) {
      timeOutHandler.removeMessages(TaskHandler.TASK_OK);
      if (!state.equals(CONTENT)) {
         state = CONTENT;
         hideLoadingView();
         hideEmptyView();
         hideErrorView();
         setContentVisibility(true, contentModel);
      }
   }

   /**
    *  
    */
   public void showLoading(ActStatusModel loadingModel) {
      timeOutHandler.removeMessages(TaskHandler.TASK_OK);
      timeOutHandler.sendSucessDelayedMessage(null, Common.TIMEOUT_TIME);
      if (!state.equals(LOADING)) {
         state = LOADING;
         hideEmptyView();
         hideErrorView();
         setLoadingView();
         setContentVisibility(false, loadingModel);
      }
   }

   /**
    *  null 
    */
   public void showEmpty(ActStatusModel emptyModel) {
      timeOutHandler.removeMessages(TaskHandler.TASK_OK);
      if (!state.equals(EMPTY)) {
         state = EMPTY;
         hideLoadingView();
         hideErrorView();
         setEmptyView();
         setContentVisibility(false, emptyModel);
      }
   }

   public void showEmpty(int resID) {
      timeOutHandler.removeMessages(TaskHandler.TASK_OK);
      if (!state.equals(EMPTY)) {
         state = EMPTY;
         emptyView = inflater.inflate(resID, null);
         layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                         ViewGroup.LayoutParams.MATCH_PARENT);
         layoutParams.addRule(CENTER_IN_PARENT);
         addView(emptyView, layoutParams);
      }
   }

   /**
    *  
    */
   public void showError(ActStatusModel errorModel) {
      timeOutHandler.removeMessages(TaskHandler.TASK_OK);
      if (!state.equals(ERROR)) {
         state = ERROR;
         hideLoadingView();
         hideEmptyView();
         setErrorView();
         if (errorModel != null && errorModel.getOnClickListener() != null) {
            errorStateImageView.setOnClickListener(errorModel.getOnClickListener());
            setContentVisibility(false, errorModel);
         } else {
            setContentVisibility(false, errorModel);
         }
      }
   }

   static class TimeOutHandler extends TaskHandler<ActivityStatusLayout> {

      public TimeOutHandler(ActivityStatusLayout activityStatusLayout) {
         super(activityStatusLayout);
      }

      @Override
      public void onTaskOk(ActivityStatusLayout activityStatusLayout, Message msg) {
         super.onTaskOk(activityStatusLayout, msg);
         Logger.e("ActivityStatusLayout = " + activityStatusLayout.toString());
         if (activityStatusLayout.isLoading()) {
            String strTimeoutTip = Common.getResString(R.string.str_timeout_tip);
            ToastTool.show(strTimeoutTip);
            activityStatusLayout.showContent(null);
         }
      }
   }

   /**
    *  
    */
   public String getState() {
      return state;
   }

   /**
    *  
    */
   public boolean isContent() {
      return state.equals(CONTENT);
   }

   /**
    *  
    */
   public boolean isLoading() {
      Logger.d("isLoading = " + state.equals(LOADING));
      Logger.d("isContent = " + isContent());
      return state.equals(LOADING);
   }

   /**
    *  
    */
   public boolean isEmpty() {
      return state.equals(EMPTY);
   }

   /**
    *  
    */
   public boolean isError() {
      return state.equals(ERROR);
   }

   private void setLoadingView() {
      if (loadingStateRelativeLayout == null) {
         View view = inflater.inflate(R.layout.progress_loading_view, null);
         ViewUtils.inject(this, view);
         loadingStateRelativeLayout.setTag(TAG_LOADING);
         layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                         ViewGroup.LayoutParams.MATCH_PARENT);
         layoutParams.addRule(CENTER_IN_PARENT);
         addView(loadingStateRelativeLayout, layoutParams);
         loadingStateRotateLoading.start();
      } else {
         loadingStateRelativeLayout.setVisibility(VISIBLE);
         loadingStateRotateLoading.stop();
      }
   }

   private void setEmptyView() {
      if (emptyStateRelativeLayout == null) {
         View view = inflater.inflate(R.layout.progress_empty_view, null);
         ViewUtils.inject(this, view);
         emptyStateRelativeLayout.setTag(TAG_EMPTY);
         emptyStateImageView.initParams();
         emptyStateTitleTextView.initParams();
         emptyStateContentTextView.initParams();
         layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                         ViewGroup.LayoutParams.MATCH_PARENT);
         layoutParams.addRule(CENTER_IN_PARENT);
         addView(emptyStateRelativeLayout, layoutParams);
      } else {
         emptyStateRelativeLayout.setVisibility(VISIBLE);
      }
   }

   private void setErrorView() {
      if (errorStateRelativeLayout == null) {
         View view = inflater.inflate(R.layout.progress_error_view, null);
         ViewUtils.inject(this, view);
         errorStateRelativeLayout.setTag(TAG_ERROR);
         errorStateImageView.initParams();
         errorStateTitleTextView.initParams();
         errorStateContentTextView.initParams();
         layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                         ViewGroup.LayoutParams.MATCH_PARENT);
         layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
         addView(errorStateRelativeLayout, layoutParams);
      } else {
         errorStateRelativeLayout.setVisibility(VISIBLE);
      }
   }

   private void hideLoadingView() {
      if (loadingStateRelativeLayout != null) {
         loadingStateRelativeLayout.setVisibility(GONE);
      }
   }


   private void hideEmptyView() {
      if (emptyStateRelativeLayout != null) {
         emptyStateRelativeLayout.setVisibility(GONE);
      }

      if (emptyView != null) {
         emptyView.setVisibility(GONE);
      }
   }

   private void hideErrorView() {
      if (errorStateRelativeLayout != null) {
         errorStateRelativeLayout.setVisibility(GONE);
      }
   }


   private boolean containsSkipId(View v, ActStatusModel actStatusModel) {
      if (actStatusModel == null) {
         return false;
      }
      List<Integer> skipIds = actStatusModel.getSkipIds();
      return skipIds != null && skipIds.size() > 0 && skipIds.contains(v.getId());
   }

   private void setContentVisibility(boolean contentVisible, ActStatusModel actStatusModel) {
      for (View v : contentViews) {
         if (!containsSkipId(v, actStatusModel)) {
            v.setVisibility(contentVisible ? View.VISIBLE : View.GONE);
         }

//       if (!skipIds.contains(v.getId())) {
//          if (contentVisible) {
//             int totalNum = ((ViewGroup) v).getChildCount();
//             Logger.e("totalNum " + totalNum);
//             for (int i = 0; i < totalNum; i++) {
//                ((ViewGroup) v).getChildAt(i).setVisibility(VISIBLE);
//             }
//             v.setVisibility(View.VISIBLE);
//          } else {
//             for (int id : skipIds) {
//                Logger.e("skipId != null " + (null != v.findViewById(id)));
//                if (null != v.findViewById(id)) {
//                   int totalNum = ((ViewGroup) v).getChildCount();
//                   Logger.e("totalNum " + totalNum);
//                   for (int i = 0; i < totalNum; i++) {
//                      int viewId = ((ViewGroup) v).getChildAt(i).getId();
//                      if (viewId == id) {
//                         ((ViewGroup) v).getChildAt(i).setVisibility(VISIBLE);
//                         Logger.e(" viewId == id ");
//                      } else {
//                         ((ViewGroup) v).getChildAt(i).setVisibility(GONE);
//                         Logger.e(" viewId != id ");
//                      }
//                   }
//                }
//             }
//          }
//          v.setVisibility(contentVisible ? View.VISIBLE : View.GONE);
//       }
      }
   }

}
二、空レイアウトlayout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:XbLP="http://schemas.android.com/apk/res-auto"
                xmlns:tv="http://schemas.android.com/apk/res-auto"
                android:id="@+id/emptyStateRelativeLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

	<LinearLayout
			android:id="@+id/emptyViewRelativeLayout"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_centerInParent="true"
			android:orientation="vertical">

		<com.xiaobai.mizar.android.ui.view.XiaobaiTextView
				android:id="@+id/emptyStateTitleTextView"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				tv:XbTvTextSize="60"
				tv:XbTvIsIOSSize="false"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_gravity="center_horizontal"
				android:textStyle="bold"
				android:text="@string/str_empty"/>

		<com.xiaobai.mizar.android.ui.view.XiaobaiTextView
				android:id="@+id/emptyStateContentTextView"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_gravity="center_horizontal"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				tv:XbTvTextSize="38"
				tv:XbTvIsIOSSize="false"
				android:gravity="center"
				android:text="@string/str_content_empty"/>

		<com.xiaobai.mizar.android.ui.view.XiaoBaiImageView
				android:id="@+id/emptyStateImageView"
				android:scaleType="fitXY"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				XbLP:XbLPMarginTop="33"
				XbLP:XbLPHeight="61"
				XbLP:XbLPWidth="61"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_gravity="center_horizontal"
				android:background="@drawable/refresh_load"/>

	</LinearLayout>

</RelativeLayout>
三、errorlayoutのロード
<?xml version="1.0" encoding="utf-8"?>
<com.xiaobai.mizar.android.ui.view.XiaoBaiRelativeLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
		xmlns:XbLP="http://schemas.android.com/apk/res-auto"
		xmlns:tv="http://schemas.android.com/apk/res-auto"
		android:id="@+id/errorStateRelativeLayout"
		android:layout_width="match_parent"
		android:layout_height="match_parent">


	<LinearLayout
			android:id="@+id/emptyViewRelativeLayout"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_centerInParent="true"
			android:orientation="vertical">

		<com.xiaobai.mizar.android.ui.view.XiaobaiTextView
				android:id="@+id/errorStateTitleTextView"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_gravity="center_horizontal"
				tv:XbTvTextSize="30"
				tv:XbTvIsIOSSize="false"
				android:textStyle="bold"
				android:textColor="@color/black"
				android:text="@string/str_load_error_tip"/>

		<com.xiaobai.mizar.android.ui.view.XiaobaiTextView
				android:id="@+id/errorStateContentTextView"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				XbLP:XbLPMarginTop="10"
				tv:XbTvTextSize="19"
				tv:XbTvIsIOSSize="false"
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:layout_gravity="center_horizontal"
				android:gravity="center"
				android:textColor="@color/black"
				android:text="@string/str_network_not_connected"/>

		<com.xiaobai.mizar.android.ui.view.XiaoBaiImageView
				android:id="@+id/errorStateImageView"
				android:scaleType="fitXY"
				XbLP:XbLPTemplateHeight="909"
				XbLP:XbLPTemplateWidth="512"
				XbLP:XbLPHeight="61"
				XbLP:XbLPWidth="61"
				XbLP:XbLPMarginTop="33"
				android:layout_width="30dp"
				android:layout_height="30dp"
				android:layout_gravity="center_horizontal"
				android:src="@drawable/refresh_load"/>

	</LinearLayout>

</com.xiaobai.mizar.android.ui.view.XiaoBaiRelativeLayout>
四、ロード中layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/loadingStateRelativeLayout"
                android:background="@color/translucent"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

	<com.base.view.RotateLoading
			xmlns:rotate="http://schemas.android.com/apk/res-auto"
			android:id="@+id/loadingStateRotateLoading"
			android:layout_centerInParent="true"
			android:layout_width="50dp"
			android:layout_height="50dp"
			rotate:loading_color="@color/main"
			rotate:loading_width="3dp"/>

</RelativeLayout>
五、使用説明:
//ロードモデルの初期化
private ActStatusModel actStatusModel = new ActStatusModel();
	private void initStatusModel() {
		actStatusModel.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				upDownPullable.initData();
			}
		});
	}

//呼び出しロード中
statusLayout.showLoading(actStatusModel);
//ロードerrorの呼び出し
statusLayout.showError(actStatusModel);
などの方法で、ロード完了後にshowContentを呼び出す.
注意:
:ここでは、カスタマイズされたロードでviewとカスタマイズされた画面が似合うtextviewなどを使っていますが、置き換えて使えばいいので、その点を知りたければ返事してください.文章を書き続けます.