Android通用LoadingView加载框架详解

作者:qq_14876133 时间:2021-12-01 10:43:24 

手写一个通用加载中、显示数据、加载失败、空数据的LoadingView框架。

Android通用LoadingView加载框架详解

定义3个布局:加载中,加载失败,空数据

加载中:


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:clickable="true">

<ProgressBar
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:indeterminate="true" />

</FrameLayout>

加载失败:


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:clickable="true"
android:orientation="vertical">

<ImageView
 android:id="@+id/error_retry"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:gravity="center"
 android:src="@drawable/loading_retry" />

</FrameLayout>

空数据:


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:clickable="true"
android:orientation="vertical">

<ImageView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:src="@drawable/loading_empty" />

</FrameLayout>

自定义一个LoadingView:


package com.sample.loadingview.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.sample.loadingview.R;

public class LoadingView extends FrameLayout {
private int emptyLayoutId, errorLayoutId, loadingLayoutId;
private View contentView, emptyView, errorView, loadingView;
private LayoutInflater mInflater;
private SparseArray<View> views = new SparseArray<>();

public LoadingView(@NonNull Context context) {
 this(context, null);
}

public LoadingView(@NonNull Context context, @Nullable AttributeSet attrs) {
 this(context, attrs, 0);
}

public LoadingView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
 super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoadLayout);
 emptyLayoutId = a.getResourceId(R.styleable.LoadLayout_emptyView, R.layout.loading_empty);
 errorLayoutId = a.getResourceId(R.styleable.LoadLayout_errorView, R.layout.loading_error);
 loadingLayoutId = a.getResourceId(R.styleable.LoadLayout_loadingView, R.layout.loading_load);
 mInflater = LayoutInflater.from(getContext());
 a.recycle();
 loadingView = mInflater.inflate(loadingLayoutId, null);
}

@Override
protected void onFinishInflate() {
 super.onFinishInflate();
 if (getChildCount() < 1) {
  throw new RuntimeException("content view can not be null");
 }
 contentView = getChildAt(0);

if (loadingView.getVisibility() != GONE)
  loadingView.setVisibility(GONE);
 addView(loadingView);
 views.put(loadingLayoutId, loadingView);
}

public void showError() {
 errorView = views.get(errorLayoutId);
 if (errorView == null) {
  errorView = mInflater.inflate(errorLayoutId, null);
  addView(errorView);
  views.put(errorLayoutId, errorView);
  final ImageView errorRetry = (ImageView) errorView.findViewById(R.id.error_retry);
  errorRetry.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    if (mOnRetryClickListener != null)
     mOnRetryClickListener.onClick(errorRetry);
   }
  });
 }
 if (errorView.getVisibility() != VISIBLE)
  errorView.setVisibility(VISIBLE);

for (int i = 0, len = views.size(); i < len; i++) {
  int key = views.keyAt(i);
  if (key != errorLayoutId) {
   View view = views.valueAt(i);
   if (view != null)
    if (view.getVisibility() != GONE)
     view.setVisibility(GONE);
  }
 }
}

public void showEmpty() {
 emptyView = views.get(emptyLayoutId);
 if (emptyView == null) {
  emptyView = mInflater.inflate(emptyLayoutId, null);
  addView(emptyView);
  views.put(emptyLayoutId, emptyView);
 }
 if (emptyView.getVisibility() != VISIBLE)
  emptyView.setVisibility(VISIBLE);

for (int i = 0, len = views.size(); i < len; i++) {
  int key = views.keyAt(i);
  if (key != emptyLayoutId) {
   View view = views.valueAt(i);
   if (view != null)
    if (view.getVisibility() != GONE)
     view.setVisibility(GONE);
  }
 }
}

public void showLoading() {
 loadingView = views.get(loadingLayoutId);
 if (loadingView.getVisibility() != VISIBLE)
  loadingView.setVisibility(VISIBLE);

for (int i = 0, len = views.size(); i < len; i++) {
  int key = views.keyAt(i);
  if (key != loadingLayoutId) {
   View view = views.valueAt(i);
   if (view != null)
    if (view.getVisibility() != GONE)
     view.setVisibility(GONE);
  }
 }
}

public void showContent() {
 for (int i = 0, len = views.size(); i < len; i++) {
  View view = views.valueAt(i);
  if (view != null)
   if (view.getVisibility() != GONE)
    view.setVisibility(GONE);
 }
}

private OnClickListener mOnRetryClickListener;

public void setOnRetryClickListener(OnClickListener onRetryClickListener) {
 this.mOnRetryClickListener = onRetryClickListener;
}
}

定义attrs.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LoadLayout">
 <attr name="loadingView" format="reference" />
 <attr name="errorView" format="reference" />
 <attr name="retryView" format="reference" />
 <attr name="emptyView" format="reference" />
</declare-styleable>
</resources>

以上就这么些代码,接下来我们测试一下

Activity


package com.sample.loadingview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.sample.loadingview.widget.LoadingView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private LoadingView loading_view;
private Button btn_loading;
private Button btn_content;
private Button btn_error;
private Button btn_empty;

@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

loading_view = (LoadingView) findViewById(R.id.loading_view);
 btn_loading = (Button) findViewById(R.id.btn_loading);
 btn_content = (Button) findViewById(R.id.btn_content);
 btn_error = (Button) findViewById(R.id.btn_error);
 btn_empty = (Button) findViewById(R.id.btn_empty);

//设置加载错误的点击事件
 loading_view.setOnRetryClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   Toast.makeText(MainActivity.this, "重新加载", Toast.LENGTH_SHORT).show();
   loading_view.showLoading();
  }
 });
 btn_loading.setOnClickListener(this);
 btn_content.setOnClickListener(this);
 btn_error.setOnClickListener(this);
 btn_empty.setOnClickListener(this);
}

@Override
public void onClick(View v) {
 switch (v.getId()) {
  case R.id.btn_loading:
   loading_view.showLoading();//显示加载界面
   break;
  case R.id.btn_content:
   loading_view.showContent();//显示内容界面
   break;
  case R.id.btn_error:
   loading_view.showError();//显示错误界面
   break;
  case R.id.btn_empty:
   loading_view.showEmpty();//显示空数据界面
   break;
 }
}
}

 源码:下载地址

来源:https://blog.csdn.net/qq_14876133/article/details/80924356

标签:Android,LoadingView,加载
0
投稿

猜你喜欢

  • Java8中Stream的一些神操作

    2021-11-18 19:07:21
  • 详解java中的static关键字

    2023-09-24 01:44:12
  • Android手势密码view学习笔记(二)

    2023-08-14 16:06:35
  • spring boot和mybatis集成分页插件

    2021-11-05 10:21:17
  • @SpringBootTest 注解报红问题及解决

    2022-08-14 23:24:51
  • java 使用HttpURLConnection发送数据简单实例

    2023-12-12 01:44:00
  • Java中常见的编码集问题总结

    2023-11-29 01:40:04
  • spring data jpa分页查询示例代码

    2023-01-09 14:51:50
  • SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    2022-02-11 02:02:13
  • Java网络编程之IO模型阻塞与非阻塞简要分析

    2021-08-10 18:10:25
  • Java matches类,Pattern类及matcher类用法示例

    2022-02-21 22:39:52
  • springboot集成@DS注解实现数据源切换的方法示例

    2021-11-18 11:30:00
  • 详解Java中的println输入和toString方法的重写问题

    2022-12-24 05:26:33
  • 详解spring cloud中使用Ribbon实现客户端的软负载均衡

    2022-10-26 15:54:45
  • C#实现调用迅雷下载的方法

    2022-03-29 12:42:21
  • 解决java 查看JDK中底层源码的实现方法

    2022-03-13 20:40:14
  • android使用viewpager计算偏移量实现选项卡功能

    2023-12-06 12:53:02
  • OpenCV + MFC实现简单人脸识别

    2023-02-24 06:15:55
  • spring boot实战教程之shiro session过期时间详解

    2023-01-05 01:37:47
  • MyBatis常用的jdbcType数据类型

    2023-09-18 19:09:35
  • asp之家 软件编程 m.aspxhome.com