content: package com.xiaochao.lcrapiddeveloplibrary.viewtype;
  
  import android.content.Context;
  import android.content.res.TypedArray;
  import android.graphics.Color;
  import android.graphics.drawable.Drawable;
  import android.support.annotation.NonNull;
  import android.util.AttributeSet;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.Button;
  import android.widget.ImageView;
  import android.widget.ProgressBar;
  import android.widget.RelativeLayout;
  import android.widget.TextView;
  
  import com.xiaochao.lcrapiddeveloplibrary.R;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  /**
   * @author Vlonjat Gashi (vlonjatg)
   */
  public class ProgressActivity extends RelativeLayout {
  
      private static final String TAG_LOADING = "ProgressActivity.TAG_LOADING";
      private static final String TAG_EMPTY = "ProgressActivity.TAG_EMPTY";
      private static final String TAG_ERROR = "ProgressActivity.TAG_ERROR";
  
      final String CONTENT = "type_content";
      final String LOADING = "type_loading";
      final String EMPTY = "type_empty";
      final String ERROR = "type_error";
  
      LayoutInflater inflater;
      View view;
      LayoutParams layoutParams;
      Drawable currentBackground;
  
      List<View> contentViews = new ArrayList<>();
  
      RelativeLayout loadingStateRelativeLayout;
      ProgressBar loadingStateProgressBar;
  
      RelativeLayout emptyStateRelativeLayout;
      ImageView emptyStateImageView;
      TextView emptyStateTitleTextView;
      TextView emptyStateContentTextView;
  
      RelativeLayout errorStateRelativeLayout;
      ImageView errorStateImageView;
      TextView errorStateTitleTextView;
      TextView errorStateContentTextView;
      Button errorStateButton;
  
      int loadingStateProgressBarWidth;
      int loadingStateProgressBarHeight;
      int loadingStateBackgroundColor;
  
      int emptyStateImageWidth;
      int emptyStateImageHeight;
      int emptyStateTitleTextSize;
      int emptyStateContentTextSize;
      int emptyStateTitleTextColor;
      int emptyStateContentTextColor;
      int emptyStateBackgroundColor;
  
      int errorStateImageWidth;
      int errorStateImageHeight;
      int errorStateTitleTextSize;
      int errorStateContentTextSize;
      int errorStateTitleTextColor;
      int errorStateContentTextColor;
      int errorStateButtonTextColor;
      int errorStateBackgroundColor;
  
      private String state = CONTENT;
  
      public ProgressActivity(Context context) {
          super(context);
      }
  
      public ProgressActivity(Context context, AttributeSet attrs) {
          super(context, attrs);
          init(attrs);
      }
  
      public ProgressActivity(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);
  
          TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressActivity);
  
          //Loading state attrs
          loadingStateProgressBarWidth =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_loadingProgressBarWidth, 250);
  
          loadingStateProgressBarHeight =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_loadingProgressBarHeight, 250);
  
          loadingStateBackgroundColor =
                  typedArray.getColor(R.styleable.ProgressActivity_loadingBackgroundColor, Color.TRANSPARENT);
  
          //Empty state attrs
          emptyStateImageWidth =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_emptyImageWidth, 308);
  
          emptyStateImageHeight =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_emptyImageHeight, 308);
  
          emptyStateTitleTextSize =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_emptyTitleTextSize, 15);
  
          emptyStateContentTextSize =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_emptyContentTextSize, 14);
  
          emptyStateTitleTextColor =
                  typedArray.getColor(R.styleable.ProgressActivity_emptyTitleTextColor, Color.BLACK);
  
          emptyStateContentTextColor =
                  typedArray.getColor(R.styleable.ProgressActivity_emptyContentTextColor, Color.BLACK);
  
          emptyStateBackgroundColor =
                  typedArray.getColor(R.styleable.ProgressActivity_emptyBackgroundColor, Color.TRANSPARENT);
  
          //Error state attrs
          errorStateImageWidth =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_errorImageWidth, 308);
  
          errorStateImageHeight =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_errorImageHeight, 308);
  
          errorStateTitleTextSize =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_errorTitleTextSize, 15);
  
          errorStateContentTextSize =
                  typedArray.getDimensionPixelSize(R.styleable.ProgressActivity_errorContentTextSize, 14);
  
          errorStateTitleTextColor =
                  typedArray.getColor(R.styleable.ProgressActivity_errorTitleTextColor, Color.BLACK);
  
          errorStateContentTextColor =
                  typedArray.getColor(R.styleable.ProgressActivity_errorContentTextColor, Color.BLACK);
  
          errorStateButtonTextColor =
                  typedArray.getColor(R.styleable.ProgressActivity_errorButtonTextColor, Color.BLACK);
  
          errorStateBackgroundColor =
                  typedArray.getColor(R.styleable.ProgressActivity_errorBackgroundColor, Color.TRANSPARENT);
  
          typedArray.recycle();
  
          currentBackground = this.getBackground();
      }
  
      @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);
          }
      }
  
      /**
       * Hide all other states and show content
       */
      public void showContent() {
          switchState(CONTENT, null, null, null, null, null, Collections.<Integer>emptyList());
      }
  
      /**
       * Hide all other states and show content
       *
       * @param skipIds Ids of views not to show
       */
      public void showContent(List<Integer> skipIds) {
          switchState(CONTENT, null, null, null, null, null, skipIds);
      }
  
      /**
       * Hide content and show the progress bar
       */
      public void showLoading() {
          switchState(LOADING, null, null, null, null, null, Collections.<Integer>emptyList());
      }
  
      /**
       * Hide content and show the progress bar
       *
       * @param skipIds Ids of views to not hide
       */
      public void showLoading(List<Integer> skipIds) {
          switchState(LOADING, null, null, null, null, null, skipIds);
      }
  
      /**
       * Show empty view when there are not data to show
       *
       * @param emptyImageDrawable Drawable to show
       * @param emptyTextTitle     Title of the empty view to show
       * @param emptyTextContent   Content of the empty view to show
       */
      public void showEmpty(Drawable emptyImageDrawable, String emptyTextTitle, String emptyTextContent) {
          switchState(EMPTY, emptyImageDrawable, emptyTextTitle, emptyTextContent, null, null, Collections.<Integer>emptyList());
      }
  
      /**
       * Show empty view when there are not data to show
       *
       * @param emptyImageDrawable Drawable to show
       * @param emptyTextTitle     Title of the empty view to show
       * @param emptyTextContent   Content of the empty view to show
       * @param skipIds            Ids of views to not hide
       */
      public void showEmpty(Drawable emptyImageDrawable, String emptyTextTitle, String emptyTextContent, List<Integer> skipIds) {
          switchState(EMPTY, emptyImageDrawable, emptyTextTitle, emptyTextContent, null, null, skipIds);
      }
  
      /**
       * Show error view with a button when something goes wrong and prompting the user to try again
       *
       * @param errorImageDrawable Drawable to show
       * @param errorTextTitle     Title of the error view to show
       * @param errorTextContent   Content of the error view to show
       * @param errorButtonText    Text on the error view button to show
       * @param onClickListener    Listener of the error view button
       */
      public void showError(Drawable errorImageDrawable, String errorTextTitle, String errorTextContent, String errorButtonText, OnClickListener onClickListener) {
          switchState(ERROR, errorImageDrawable, errorTextTitle, errorTextContent, errorButtonText, onClickListener, Collections.<Integer>emptyList());
      }
  
      /**
       * Show error view with a button when something goes wrong and prompting the user to try again
       *
       * @param errorImageDrawable Drawable to show
       * @param errorTextTitle     Title of the error view to show
       * @param errorTextContent   Content of the error view to show
       * @param errorButtonText    Text on the error view button to show
       * @param onClickListener    Listener of the error view button
       * @param skipIds            Ids of views to not hide
       */
      public void showError(Drawable errorImageDrawable, String errorTextTitle, String errorTextContent, String errorButtonText, OnClickListener onClickListener, List<Integer> skipIds) {
          switchState(ERROR, errorImageDrawable, errorTextTitle, errorTextContent, errorButtonText, onClickListener, skipIds);
      }
  
      /**
       * Get which state is set
       *
       * @return State
       */
      public String getState() {
          return state;
      }
  
      /**
       * Check if content is shown
       *
       * @return boolean
       */
      public boolean isContent() {
          return state.equals(CONTENT);
      }
  
      /**
       * Check if loading state is shown
       *
       * @return boolean
       */
      public boolean isLoading() {
          return state.equals(LOADING);
      }
  
      /**
       * Check if empty state is shown
       *
       * @return boolean
       */
      public boolean isEmpty() {
          return state.equals(EMPTY);
      }
  
      /**
       * Check if error state is shown
       *
       * @return boolean
       */
      public boolean isError() {
          return state.equals(ERROR);
      }
  
      private void switchState(String state, Drawable drawable, String errorText, String errorTextContent,
                               String errorButtonText, OnClickListener onClickListener, List<Integer> skipIds) {
          this.state = state;
  
          switch (state) {
              case CONTENT:
                  //Hide all state views to display content
                  hideLoadingView();
                  hideEmptyView();
                  hideErrorView();
  
                  setContentVisibility(true, skipIds);
                  break;
              case LOADING:
                  hideEmptyView();
                  hideErrorView();
  
                  setLoadingView();
                  setContentVisibility(false, skipIds);
                  break;
              case EMPTY:
                  hideLoadingView();
                  hideErrorView();
  
                  setEmptyView();
                  emptyStateImageView.setImageDrawable(drawable);
                  emptyStateTitleTextView.setText(errorText);
                  emptyStateContentTextView.setText(errorTextContent);
                  setContentVisibility(false, skipIds);
                  break;
              case ERROR:
                  hideLoadingView();
                  hideEmptyView();
  
                  setErrorView();
                  errorStateImageView.setImageDrawable(drawable);
                  errorStateTitleTextView.setText(errorText);
                  errorStateContentTextView.setText(errorTextContent);
                  errorStateButton.setText(errorButtonText);
                  errorStateButton.setOnClickListener(onClickListener);
                  setContentVisibility(false, skipIds);
                  break;
          }
      }
  
      private void setLoadingView() {
          if (loadingStateRelativeLayout == null) {
              view = inflater.inflate(R.layout.progress_loading_view, null);
              loadingStateRelativeLayout = (RelativeLayout) view.findViewById(R.id.loadingStateRelativeLayout);
              loadingStateRelativeLayout.setTag(TAG_LOADING);
  
              loadingStateProgressBar = (ProgressBar) view.findViewById(R.id.loadingStateProgressBar);
  
              loadingStateProgressBar.getLayoutParams().width = loadingStateProgressBarWidth;
              loadingStateProgressBar.getLayoutParams().height = loadingStateProgressBarHeight;
              loadingStateProgressBar.requestLayout();
  
              //Set background color if not TRANSPARENT
              if (loadingStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundColor(loadingStateBackgroundColor);
              }
  
              layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                      ViewGroup.LayoutParams.MATCH_PARENT);
              layoutParams.addRule(CENTER_IN_PARENT);
  
              addView(loadingStateRelativeLayout, layoutParams);
          } else {
              loadingStateRelativeLayout.setVisibility(VISIBLE);
          }
      }
  
      private void setEmptyView() {
          if (emptyStateRelativeLayout == null) {
              view = inflater.inflate(R.layout.progress_empty_view, null);
              emptyStateRelativeLayout = (RelativeLayout) view.findViewById(R.id.emptyStateRelativeLayout);
              emptyStateRelativeLayout.setTag(TAG_EMPTY);
  
              emptyStateImageView = (ImageView) view.findViewById(R.id.emptyStateImageView);
              emptyStateTitleTextView = (TextView) view.findViewById(R.id.emptyStateTitleTextView);
              emptyStateContentTextView = (TextView) view.findViewById(R.id.emptyStateContentTextView);
  
              //Set empty state image width and height
              emptyStateImageView.getLayoutParams().width = emptyStateImageWidth;
              emptyStateImageView.getLayoutParams().height = emptyStateImageHeight;
              emptyStateImageView.requestLayout();
  
              emptyStateTitleTextView.setTextSize(emptyStateTitleTextSize);
              emptyStateContentTextView.setTextSize(emptyStateContentTextSize);
              emptyStateTitleTextView.setTextColor(emptyStateTitleTextColor);
              emptyStateContentTextView.setTextColor(emptyStateContentTextColor);
  
              //Set background color if not TRANSPARENT
              if (emptyStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundColor(emptyStateBackgroundColor);
              }
  
              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 = inflater.inflate(R.layout.progress_error_view, null);
              errorStateRelativeLayout = (RelativeLayout) view.findViewById(R.id.errorStateRelativeLayout);
              errorStateRelativeLayout.setTag(TAG_ERROR);
  
              errorStateImageView = (ImageView) view.findViewById(R.id.errorStateImageView);
              errorStateTitleTextView = (TextView) view.findViewById(R.id.errorStateTitleTextView);
              errorStateContentTextView = (TextView) view.findViewById(R.id.errorStateContentTextView);
              errorStateButton = (Button) view.findViewById(R.id.errorStateButton);
  
              //Set error state image width and height
              errorStateImageView.getLayoutParams().width = errorStateImageWidth;
              errorStateImageView.getLayoutParams().height = errorStateImageHeight;
              errorStateImageView.requestLayout();
  
              errorStateTitleTextView.setTextSize(errorStateTitleTextSize);
              errorStateContentTextView.setTextSize(errorStateContentTextSize);
              errorStateTitleTextView.setTextColor(errorStateTitleTextColor);
              errorStateContentTextView.setTextColor(errorStateContentTextColor);
              errorStateButton.setTextColor(errorStateButtonTextColor);
  
              //Set background color if not TRANSPARENT
              if (errorStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundColor(errorStateBackgroundColor);
              }
  
              layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                      ViewGroup.LayoutParams.MATCH_PARENT);
              layoutParams.addRule(CENTER_IN_PARENT);
  
              addView(errorStateRelativeLayout, layoutParams);
          } else {
              errorStateRelativeLayout.setVisibility(VISIBLE);
          }
      }
  
      private void setContentVisibility(boolean visible, List<Integer> skipIds) {
          for (View v : contentViews) {
              if (!skipIds.contains(v.getId())) {
                  v.setVisibility(visible ? View.VISIBLE : View.GONE);
              }
          }
      }
  
      private void hideLoadingView() {
          if (loadingStateRelativeLayout != null) {
              loadingStateRelativeLayout.setVisibility(GONE);
  
              //Restore the background color if not TRANSPARENT
              if (loadingStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundDrawable(currentBackground);
              }
          }
      }
  
      private void hideEmptyView() {
          if (emptyStateRelativeLayout != null) {
              emptyStateRelativeLayout.setVisibility(GONE);
  
              //Restore the background color if not TRANSPARENT
              if (emptyStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundDrawable(currentBackground);;
              }
          }
      }
  
      private void hideErrorView() {
          if (errorStateRelativeLayout != null) {
              errorStateRelativeLayout.setVisibility(GONE);
  
              //Restore the background color if not TRANSPARENT
              if (errorStateBackgroundColor != Color.TRANSPARENT) {
                  this.setBackgroundDrawable(currentBackground);;
              }
  
          }
      }
  }