/*
* Copyright (c) 2016 Zhang Hai <Dreaming.in.Code.ZH@Gmail.com>
* All Rights Reserved.
*/
package me.zhanghai.android.douya.ui;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.IntDef;
import android.support.v7.widget.TintTypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import me.zhanghai.android.douya.R;
import me.zhanghai.android.douya.util.ViewUtils;
public class ContentStateLayout extends FrameLayout {
@IntDef({STATE_LOADING, STATE_CONTENT, STATE_EMPTY, STATE_ERROR})
@Retention(RetentionPolicy.SOURCE)
public @interface State {}
public static final int STATE_LOADING = 0;
public static final int STATE_CONTENT = 1;
public static final int STATE_EMPTY = 2;
public static final int STATE_ERROR = 3;
private int mLoadingViewId;
private int mContentViewId;
private int mEmptyViewId;
private int mErrorViewId;
private View mLoadingView;
private View mContentView;
private View mEmptyView;
private View mErrorView;
private boolean mAnimationEnabled;
public ContentStateLayout(Context context) {
super(context);
init(null, 0, 0);
}
public ContentStateLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0, 0);
}
public ContentStateLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr, 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ContentStateLayout(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs, defStyleAttr, defStyleRes);
}
@SuppressWarnings("RestrictedApi")
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
R.styleable.ContentStateLayout, defStyleAttr, defStyleRes);
mLoadingViewId = a.getResourceId(R.styleable.ContentStateLayout_loadingView, R.id.loading);
mContentViewId = a.getResourceId(R.styleable.ContentStateLayout_contentView, R.id.content);
mEmptyViewId = a.getResourceId(R.styleable.ContentStateLayout_emptyView, R.id.empty);
mErrorViewId = a.getResourceId(R.styleable.ContentStateLayout_errorView, R.id.error);
mAnimationEnabled = a.getBoolean(R.styleable.ContentStateLayout_animationEnabled, true);
a.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLoadingView = findChildById(mLoadingViewId);
mContentView = findChildById(mContentViewId);
mEmptyView = findChildById(mEmptyViewId);
mErrorView = findChildById(mErrorViewId);
if (mLoadingView == null) {
mLoadingView = LayoutInflater.from(getContext())
.inflate(R.layout.content_layout_default_loading_view, this, false);
addView(mLoadingView);
}
setViewVisible(mLoadingView, false, false);
setViewVisible(mContentView, false, false);
setViewVisible(mEmptyView, false, false);
setViewVisible(mErrorView, false, false);
}
private View findChildById(int id) {
for (int i = 0, count = getChildCount(); i < count; ++i) {
View child = getChildAt(i);
if (child.getId() == id) {
return child;
}
}
return null;
}
public View getLoadingView() {
return mLoadingView;
}
public View getContentView() {
return mContentView;
}
public View getEmptyView() {
return mEmptyView;
}
public View getErrorView() {
return mErrorView;
}
public boolean isAnimationEnabled() {
return mAnimationEnabled;
}
public void setAnimationEnabled(boolean enabled) {
mAnimationEnabled = enabled;
}
public void setState(@State int state) {
setViewVisible(mLoadingView, state == STATE_LOADING);
setViewVisible(mContentView, state == STATE_CONTENT);
setViewVisible(mEmptyView, state == STATE_EMPTY);
setViewVisible(mErrorView, state == STATE_ERROR);
}
public void setLoading() {
setState(STATE_LOADING);
}
public void setLoaded(boolean hasContent) {
setState(hasContent ? STATE_CONTENT : STATE_EMPTY);
}
public void setError() {
setState(STATE_ERROR);
}
private void setViewVisible(View view, boolean visible, boolean animate) {
if (view == null) {
if (visible) {
// TODO: Be more detailed.
throw new IllegalStateException("Missing view when setting to visible");
} else {
return;
}
}
if (animate) {
ViewUtils.fadeToVisibility(view, visible);
} else {
ViewUtils.setVisibleOrGone(view, visible);
}
}
private void setViewVisible(View view, boolean visible) {
setViewVisible(view, visible, mAnimationEnabled);
}
}