做项目当中总是遇到页面数据加载的情况,自定义了几个加载情况的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, attrs, 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);
}
时间: 2024-10-14 13:16:47