做项目当中总是遇到页面数据加载的情况,自定义了几个加载情况的xml布局,例如加载失败,加载数据为空,加载成功,正在加载等,但是发现每次都需要根据加载情况去处理显示哪种xml,很麻烦,也很容易出错,所以我就想以自定义组合控件的方式来处理,达到复用的目的,代码可优化的地方有很多,大家可以根据自己的需求做修改。
首先自定义属性了:
<!--loadinglayout-->
<declare-styleable name="LoadingLayout">
<attr name="loadingLayoutId" format="reference"/>
<attr name="failureLayoutId" format="reference"/>
<attr name="emptyLayoutId" format="reference"/>
<attr name="contentId" format="reference"/>
</declare-styleable>
代码很简单,自己看看
public class LoadingLayout extends FrameLayout {
private View loadingView,failureView,emptyView,contentView;
private RetryListener retryListener;
public LoadingLayout(Context context,AttributeSet attrs) {
this(context,attrs,0);
}
public LoadingLayout(Context context) {
this(context,null);
}
public LoadingLayout(Context context,AttributeSet attrs,int defStyleAttr) {
super(context,defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.LoadingLayout,defStyleAttr,0);
int loadingId = typedArray.getResourceId(R.styleable.LoadingLayout_loadingLayoutId,0);
int failureId = typedArray.getResourceId(R.styleable.LoadingLayout_failureLayoutId,0);
int emptyId = typedArray.getResourceId(R.styleable.LoadingLayout_emptyLayoutId,0);
int contentId = typedArray.getResourceId(R.styleable.LoadingLayout_contentId,0);
typedArray.recycle();
initView(context,loadingId,failureId,emptyId,contentId);
}
//初始化三个状态View
private void initView(Context context,int loadingId,int failureId,int emptyId,int contentId) {
createChildView(context,loadingId);
createChildView(context,failureId);
createChildView(context,emptyId);
createChildView(context,contentId);
}
//创建子视图
private void createChildView(Context context,int Id) {
if (Id!=0) {
View.inflate(context,Id,this);
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//获取显示内容区域
if (getChildCount() > 3) {
loadingView = getChildAt(0);
failureView = getChildAt(1);
emptyView = getChildAt(2);
contentView = getChildAt(3);
contentView.setVisibility(GONE);
if (loadingView != null) {
loadingView.setVisibility(GONE);
}
if (failureView != null) {
failureView.setVisibility(GONE);
View rButton = (failureView.findViewById(R.id.tv_retry) == null) ? failureView : failureView.findViewById(R.id.tv_retry);
rButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (retryListener != null) {
retryListener.retryClick();
}
}
});
}
if (emptyView != null) {
emptyView.setVisibility(GONE);
}
}
}
//设置重试监听
public void setRetryListener(RetryListener retryListener) {
this.retryListener = retryListener;
}
//显示加载view
public void showLoading() {
show(1);
}
//显示失败view
public void showFailure() {
show(2);
}
//显示空view
public void showEmpty() {
show(3);
}
//显示空view
public void showContent() {
show(4);
}
//根据id展示布局
private void show(int id) {
if (loadingView != null) {
loadingView.setVisibility(id == 1 ? VISIBLE : GONE);
}
if (failureView != null) {
failureView.setVisibility(id == 2 ? VISIBLE : GONE);
}
if (emptyView != null) {
emptyView.setVisibility(id == 3 ? VISIBLE : GONE);
}
if (contentView != null) {
contentView.setVisibility(id == 4 ? VISIBLE : GONE);
}
}
public interface RetryListener {
void retryClick();
}
}
然后就是如何使用了
<?xml version="1.0" encoding="utf-8"?> <com.yjjy.app.view.LoadingLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/loadingLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:loadingLayoutId="@layout/progressdialoag" app:failureLayoutId="@layout/loading_failure" <!--可以在这里引用设置contentlayout--> > <!--也可以在这里引用设置contentlayout--> </com.yjjy.app.view.LoadingLayout>
//显示加载view
public void showLoading() {
show(1);
}
//显示失败view
public void showFailure() {
show(2);
}
//显示空view
public void showEmpty() {
show(3);
}
//显示空view
public void showContent() {
show(4);
}