package com.kanak.emptylayout; import com.kanak.emptylayout.R; import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.widget.TextView; public class EmptyLayout { private Context mContext; private ViewGroup mLoadingView; private ViewGroup mEmptyView; private ViewGroup mErrorView; //private Animation mLoadingAnimation; private ProgressBar mProgressBar; private ListView mListView; private int mErrorMessageViewId; private int mEmptyMessageViewId; private int mLoadingMessageViewId; private LayoutInflater mInflater; private boolean mViewsAdded; private int mLoadingAnimationViewId; private View.OnClickListener mLoadingButtonClickListener; private View.OnClickListener mEmptyButtonClickListener; private View.OnClickListener mErrorButtonClickListener; // --------------------------- // static variables // --------------------------- /** * The empty state */ public final static int TYPE_EMPTY = 1; /** * The loading state */ public final static int TYPE_LOADING = 2; /** * The error state */ public final static int TYPE_ERROR = 3; /** * The normal state */ public final static int TYPE_NORMAL = 4; // --------------------------- // default values // --------------------------- private int mEmptyType = TYPE_LOADING; private String mErrorMessage = "Oops! Something wrong happened"; private String mEmptyMessage = "No items yet"; private String mLoadingMessage = "Please wait"; private int mLoadingViewButtonId = R.id.buttonLoading; private int mErrorViewButtonId = R.id.buttonError; private int mEmptyViewButtonId = R.id.buttonEmpty; private boolean mShowEmptyButton = true; private boolean mShowLoadingButton = true; private boolean mShowErrorButton = true; private int mIndeterminateDrawable = R.drawable.progress; private int mProgressBarBackground = R.drawable.ic_background; // --------------------------- // getters and setters // --------------------------- /** * Gets the loading layout * @return the loading layout */ public ViewGroup getLoadingView() { return mLoadingView; } /** * Sets loading layout * @param loadingView the layout to be shown when the list is loading */ public void setLoadingView(ViewGroup loadingView) { this.mLoadingView = loadingView; } /** * Sets loading layout resource * @param res the resource of the layout to be shown when the list is loading */ public void setLoadingViewRes(int res){ this.mLoadingView = (ViewGroup) mInflater.inflate(res, null); } /** * Gets the empty layout * @return the empty layout */ public ViewGroup getEmptyView() { return mEmptyView; } /** * Sets empty layout * @param emptyView the layout to be shown when no items are available to load in the list */ public void setEmptyView(ViewGroup emptyView) { this.mEmptyView = emptyView; } /** * Sets empty layout resource * @param res the resource of the layout to be shown when no items are available to load in the list */ public void setEmptyViewRes(int res){ this.mEmptyView = (ViewGroup) mInflater.inflate(res, null); } /** * Gets the error layout * @return the error layout */ public ViewGroup getErrorView() { return mErrorView; } /** * Sets error layout * @param errorView the layout to be shown when list could not be loaded due to some error */ public void setErrorView(ViewGroup errorView) { this.mErrorView = errorView; } /** * Sets error layout resource * @param res the resource of the layout to be shown when list could not be loaded due to some error */ public void setErrorViewRes(int res){ this.mErrorView = (ViewGroup) mInflater.inflate(res, null); } // /** // * Gets the loading animation // * @return the loading animation // */ // public Animation getLoadingAnimation() { // return mLoadingAnimation; // } // // /** // * Sets the loading animation // * @param animation the animation to play when the list is being loaded // */ // public void setLoadingAnimation(Animation animation) { // this.mLoadingAnimation = animation; // } // // /** // * Sets the resource of loading animation // * @param animationResource the animation resource to play when the list is being loaded // */ // public void setLoadingAnimationRes(int animationResource) { // mLoadingAnimation = AnimationUtils.loadAnimation(mContext, animationResource); // } public int getProgressBarBackground(){ return mProgressBarBackground; } public void setLoadingRes(int resId){ mProgressBarBackground = resId; mProgressBar.setBackgroundResource(resId); } public int getIndeterminateDrawable(){ return mIndeterminateDrawable; } public void setIndeterminateDrawable(int drawableId){ mIndeterminateDrawable = drawableId; mProgressBar.setIndeterminateDrawable(mContext.getResources().getDrawable(drawableId)); } /** * Gets the list view for which this library is being used * @return the list view */ public ListView getListView() { return mListView; } /** * Sets the list view for which this library is being used * @param listView */ public void setListView(ListView listView) { this.mListView = listView; } /** * Gets the last set state of the list view * @return loading or empty or error */ public int getEmptyType() { return mEmptyType; } /** * Sets the state of the empty view of the list view * @param emptyType loading or empty or error */ public void setEmptyType(int emptyType) { this.mEmptyType = emptyType; changeEmptyType(); } /** * Gets the message which is shown when the list could not be loaded due to some error * @return the error message */ public String getErrorMessage() { return mErrorMessage; } /** * Sets the message to be shown when the list could not be loaded due to some error * @param errorMessage the error message * @param messageViewId the id of the text view within the error layout whose text will be changed into this message */ public void setErrorMessage(String errorMessage, int messageViewId) { this.mErrorMessage = errorMessage; this.mErrorMessageViewId = messageViewId; } /** * Sets the message to be shown when the list could not be loaded due to some error * @param errorMessage the error message */ public void setErrorMessage(String errorMessage) { this.mErrorMessage = errorMessage; } /** * Gets the message which will be shown when the list will be empty for not having any item to display * @return the message which will be shown when the list will be empty for not having any item to display */ public String getEmptyMessage() { return mEmptyMessage; } /** * Sets the message to be shown when the list will be empty for not having any item to display * @param emptyMessage the message * @param messageId the id of the text view within the empty layout whose text will be changed into this message */ public void setEmptyMessage(String emptyMessage, int messageViewId) { this.mEmptyMessage = emptyMessage; this.mEmptyMessageViewId = messageViewId; } /** * Sets the message to be shown when the list will be empty for not having any item to display * @param emptyMessage the message */ public void setEmptyMessage(String emptyMessage) { this.mEmptyMessage = emptyMessage; } /** * Gets the message which will be shown when the list is being loaded * @return */ public String getLoadingMessage() { return mLoadingMessage; } /** * Sets the message to be shown when the list is being loaded * @param loadingMessage the message * @param messageViewId the id of the text view within the loading layout whose text will be changed into this message */ public void setLoadingMessage(String loadingMessage, int messageViewId) { this.mLoadingMessage = loadingMessage; this.mLoadingMessageViewId = messageViewId; } /** * Sets the message to be shown when the list is being loaded * @param loadingMessage the message */ public void setLoadingMessage(String loadingMessage) { this.mLoadingMessage = loadingMessage; } /** * Gets the view in the loading layout which will be animated when the list is being loaded * @return the view in the loading layout which will be animated when the list is being loaded */ public int getLoadingAnimationViewId() { return mLoadingAnimationViewId; } /** * Sets the view in the loading layout which will be animated when the list is being loaded * @param loadingAnimationViewId the id of the view */ public void setLoadingAnimationViewId(int loadingAnimationViewId) { this.mLoadingAnimationViewId = loadingAnimationViewId; } /** * Gets the OnClickListener which perform when LoadingView was click * @return */ public View.OnClickListener getLoadingButtonClickListener() { return mLoadingButtonClickListener; } /** * Sets the OnClickListener to LoadingView * @param loadingButtonClickListener OnClickListener Object */ public void setLoadingButtonClickListener(View.OnClickListener loadingButtonClickListener) { this.mLoadingButtonClickListener = loadingButtonClickListener; } /** * Gets the OnClickListener which perform when EmptyView was click * @return */ public View.OnClickListener getEmptyButtonClickListener() { return mEmptyButtonClickListener; } /** * Sets the OnClickListener to EmptyView * @param emptyButtonClickListener OnClickListener Object */ public void setEmptyButtonClickListener(View.OnClickListener emptyButtonClickListener) { this.mEmptyButtonClickListener = emptyButtonClickListener; } /** * Gets the OnClickListener which perform when ErrorView was click * @return */ public View.OnClickListener getErrorButtonClickListener() { return mErrorButtonClickListener; } /** * Sets the OnClickListener to ErrorView * @param errorButtonClickListener OnClickListener Object */ public void setErrorButtonClickListener(View.OnClickListener errorButtonClickListener) { this.mErrorButtonClickListener = errorButtonClickListener; } /** * Gets if a button is shown in the empty view * @return if a button is shown in the empty view */ public boolean isEmptyButtonShown() { return mShowEmptyButton; } /** * Sets if a button will be shown in the empty view * @param showEmptyButton will a button be shown in the empty view */ public void setShowEmptyButton(boolean showEmptyButton) { this.mShowEmptyButton = showEmptyButton; } /** * Gets if a button is shown in the loading view * @return if a button is shown in the loading view */ public boolean isLoadingButtonShown() { return mShowLoadingButton; } /** * Sets if a button will be shown in the loading view * @param showEmptyButton will a button be shown in the loading view */ public void setShowLoadingButton(boolean showLoadingButton) { this.mShowLoadingButton = showLoadingButton; } /** * Gets if a button is shown in the error view * @return if a button is shown in the error view */ public boolean isErrorButtonShown() { return mShowErrorButton; } /** * Sets if a button will be shown in the error view * @param showEmptyButton will a button be shown in the error view */ public void setShowErrorButton(boolean showErrorButton) { this.mShowErrorButton = showErrorButton; } /** * Gets the ID of the button in the loading view * @return the ID of the button in the loading view */ public int getmLoadingViewButtonId() { return mLoadingViewButtonId; } /** * Sets the ID of the button in the loading view. This ID is required if you want the button the loading view to be click-able. * @param loadingViewButtonId the ID of the button in the loading view */ public void setLoadingViewButtonId(int loadingViewButtonId) { this.mLoadingViewButtonId = loadingViewButtonId; } /** * Gets the ID of the button in the error view * @return the ID of the button in the error view */ public int getErrorViewButtonId() { return mErrorViewButtonId; } /** * Sets the ID of the button in the error view. This ID is required if you want the button the error view to be click-able. * @param errorViewButtonId the ID of the button in the error view */ public void setErrorViewButtonId(int errorViewButtonId) { this.mErrorViewButtonId = errorViewButtonId; } /** * Gets the ID of the button in the empty view * @return the ID of the button in the empty view */ public int getEmptyViewButtonId() { return mEmptyViewButtonId; } /** * Sets the ID of the button in the empty view. This ID is required if you want the button the empty view to be click-able. * @param emptyViewButtonId the ID of the button in the empty view */ public void setEmptyViewButtonId(int emptyViewButtonId) { this.mEmptyViewButtonId = emptyViewButtonId; } // --------------------------- // private methods // --------------------------- private void changeEmptyType() { setDefaultValues(); refreshMessages(); // insert views in the root view if (!mViewsAdded) { RelativeLayout.LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.addRule(RelativeLayout.CENTER_HORIZONTAL); lp.addRule(RelativeLayout.CENTER_VERTICAL); RelativeLayout rl = new RelativeLayout(mContext); rl.setLayoutParams(lp); if (mEmptyView!=null) rl.addView(mEmptyView); if (mLoadingView!=null) rl.addView(mLoadingView); if (mErrorView!=null) rl.addView(mErrorView); mViewsAdded = true; ViewGroup parent = (ViewGroup) mListView.getParent(); parent.addView(rl); mListView.setEmptyView(rl); } // change empty type if (mListView!=null) { View loadingAnimationView = null; if (mLoadingAnimationViewId != R.id.imageViewLoading) loadingAnimationView = ((Activity) mContext).findViewById(mLoadingAnimationViewId); else loadingAnimationView = mLoadingView.findViewById(R.id.imageViewLoading); switch (mEmptyType) { case TYPE_EMPTY: if (mEmptyView!=null) mEmptyView.setVisibility(View.VISIBLE); if (mErrorView!=null) mErrorView.setVisibility(View.GONE); if (mLoadingView!=null) { mLoadingView.setVisibility(View.GONE); if (loadingAnimationView!=null && loadingAnimationView.getAnimation()!=null) loadingAnimationView.getAnimation().cancel(); } break; case TYPE_ERROR: if (mEmptyView!=null) mEmptyView.setVisibility(View.GONE); if (mErrorView!=null) mErrorView.setVisibility(View.VISIBLE); if (mLoadingView!=null) { mLoadingView.setVisibility(View.GONE); if (loadingAnimationView!=null && loadingAnimationView.getAnimation()!=null) loadingAnimationView.getAnimation().cancel(); } break; case TYPE_LOADING: if (mEmptyView!=null) mEmptyView.setVisibility(View.GONE); if (mErrorView!=null) mErrorView.setVisibility(View.GONE); if (mLoadingView!=null) { mLoadingView.setVisibility(View.VISIBLE); // if (mLoadingAnimation != null && loadingAnimationView!=null) { // loadingAnimationView.startAnimation(mLoadingAnimation); // } //else // if (loadingAnimationView!=null) { // loadingAnimationView.startAnimation(getRotateAnimation()); // } } break; case TYPE_NORMAL: if (mEmptyView!=null) mEmptyView.setVisibility(View.GONE); if (mErrorView!=null) mErrorView.setVisibility(View.GONE); if (mLoadingView!=null) mLoadingView.setVisibility(View.GONE); if (mListView!=null) mListView.setVisibility(View.VISIBLE); break; default: break; } } } private void refreshMessages() { if (mEmptyMessageViewId>0 && mEmptyMessage!=null) ((TextView)mEmptyView.findViewById(mEmptyMessageViewId)).setText(mEmptyMessage); if (mLoadingMessageViewId>0 && mLoadingMessage!=null) ((TextView)mLoadingView.findViewById(mLoadingMessageViewId)).setText(mLoadingMessage); if (mErrorMessageViewId>0 && mErrorMessage!=null) ((TextView)mErrorView.findViewById(mErrorMessageViewId)).setText(mErrorMessage); } private void setDefaultValues() { if (mEmptyView==null) { mEmptyView = (ViewGroup) mInflater.inflate(R.layout.view_empty, null); if (!(mEmptyMessageViewId>0)) mEmptyMessageViewId = R.id.textViewMessage; if (mShowEmptyButton && mEmptyViewButtonId>0 && mEmptyButtonClickListener!=null) { View emptyViewButton = mEmptyView.findViewById(mEmptyViewButtonId); if (emptyViewButton != null) { emptyViewButton.setOnClickListener(mEmptyButtonClickListener); emptyViewButton.setVisibility(View.VISIBLE); } } else if (mEmptyViewButtonId>0) { View emptyViewButton = mEmptyView.findViewById(mEmptyViewButtonId); emptyViewButton.setVisibility(View.GONE); } } if (mLoadingView==null) { mLoadingView = (ViewGroup) mInflater.inflate(R.layout.view_loading, null); mProgressBar = (ProgressBar)mLoadingView.findViewById(R.id.imageViewLoading); mLoadingAnimationViewId = R.id.imageViewLoading; if (!(mLoadingMessageViewId>0)) mLoadingMessageViewId = R.id.textViewMessage; if (mShowLoadingButton && mLoadingViewButtonId>0 && mLoadingButtonClickListener!=null) { View loadingViewButton = mLoadingView.findViewById(mLoadingViewButtonId); if (loadingViewButton != null) { loadingViewButton.setOnClickListener(mLoadingButtonClickListener); loadingViewButton.setVisibility(View.VISIBLE); } } else if (mLoadingViewButtonId>0) { View loadingViewButton = mLoadingView.findViewById(mLoadingViewButtonId); loadingViewButton.setVisibility(View.GONE); } } if (mErrorView==null) { mErrorView = (ViewGroup) mInflater.inflate(R.layout.view_error, null); if (!(mErrorMessageViewId>0)) mErrorMessageViewId = R.id.textViewMessage; if (mShowErrorButton && mErrorViewButtonId>0 && mErrorButtonClickListener!=null) { View errorViewButton = mErrorView.findViewById(mErrorViewButtonId); if (errorViewButton != null) { errorViewButton.setOnClickListener(mErrorButtonClickListener); errorViewButton.setVisibility(View.VISIBLE); } } else if (mErrorViewButtonId>0) { View errorViewButton = mErrorView.findViewById(mErrorViewButtonId); errorViewButton.setVisibility(View.GONE); } } } private static Animation getRotateAnimation() { final RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f); rotateAnimation.setDuration(1500); rotateAnimation.setInterpolator(new LinearInterpolator()); rotateAnimation.setRepeatCount(Animation.INFINITE); return rotateAnimation; } // --------------------------- // public methods // --------------------------- /** * Constructor * @param context the context (preferred context is any activity) */ public EmptyLayout(Context context) { mContext = context; mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * Constructor * @param context the context (preferred context is any activity) * @param listView the list view for which this library is being used */ public EmptyLayout(Context context, ListView listView) { mContext = context; mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mListView = listView; } /** * Shows the empty layout if the list is empty */ public void showEmpty() { this.mEmptyType = TYPE_EMPTY; changeEmptyType(); } /** * Shows loading layout if the list is empty */ public void showLoading() { this.mEmptyType = TYPE_LOADING; changeEmptyType(); } /** * Shows error layout if the list is empty */ public void showError() { this.mEmptyType = TYPE_ERROR; changeEmptyType(); } /** * Shows list view when is not empty */ public void showListView() { this.mEmptyType = TYPE_NORMAL; changeEmptyType(); } }