first commit

This commit is contained in:
renjianbo
2025-12-26 15:36:42 +08:00
parent 68054948d0
commit dd2a978bd3
3679 changed files with 306133 additions and 0 deletions

2
multiple-status-view/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/build
*.iml

View File

@@ -0,0 +1,23 @@
apply plugin: 'com.android.library'
android {
namespace 'com.classic.common'
compileSdk rootProject.ext.android.compileSdkVersion
compileSdkVersion rootProject.ext.android.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies { }

17
multiple-status-view/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\AndroidStudio\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.classic.common"/>

View File

@@ -0,0 +1,296 @@
package com.classic.common;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import java.util.ArrayList;
/**
* 类描述: 一个方便在多种状态切换的view
*
* 创建时间: 2016/1/15 10:20.
*/
@SuppressWarnings("unused")
public class MultipleStatusView extends RelativeLayout {
private static final String TAG = "MultipleStatusView";
private static final RelativeLayout.LayoutParams DEFAULT_LAYOUT_PARAMS =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
public static final int STATUS_CONTENT = 0x00;
public static final int STATUS_LOADING = 0x01;
public static final int STATUS_EMPTY = 0x02;
public static final int STATUS_ERROR = 0x03;
public static final int STATUS_NO_NETWORK = 0x04;
private static final int NULL_RESOURCE_ID = -1;
private View mEmptyView;
private View mErrorView;
private View mLoadingView;
private View mNoNetworkView;
private View mContentView;
private int mEmptyViewResId;
private int mErrorViewResId;
private int mLoadingViewResId;
private int mNoNetworkViewResId;
private int mContentViewResId;
private int mViewStatus;
private LayoutInflater mInflater;
private OnClickListener mOnRetryClickListener;
private final ArrayList<Integer> mOtherIds = new ArrayList<>();
public MultipleStatusView(Context context) {
this(context, null);
}
public MultipleStatusView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MultipleStatusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultipleStatusView, defStyleAttr, 0);
mEmptyViewResId = a.getResourceId(R.styleable.MultipleStatusView_emptyView, R.layout.empty_view);
mErrorViewResId = a.getResourceId(R.styleable.MultipleStatusView_errorView, R.layout.error_view);
mLoadingViewResId = a.getResourceId(R.styleable.MultipleStatusView_loadingView, R.layout.loading_view);
mNoNetworkViewResId = a.getResourceId(R.styleable.MultipleStatusView_noNetworkView, R.layout.no_network_view);
mContentViewResId = a.getResourceId(R.styleable.MultipleStatusView_contentView, NULL_RESOURCE_ID);
a.recycle();
mInflater = LayoutInflater.from(getContext());
}
@Override protected void onFinishInflate() {
super.onFinishInflate();
showContent();
}
@Override protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
clear(mEmptyView, mLoadingView, mErrorView, mNoNetworkView);
if (null != mOtherIds) {
mOtherIds.clear();
}
if (null != mOnRetryClickListener) {
mOnRetryClickListener = null;
}
mInflater = null;
}
/**
* 获取当前状态
*/
public int getViewStatus() {
return mViewStatus;
}
/**
* 设置重试点击事件
*
* @param onRetryClickListener 重试点击事件
*/
public void setOnRetryClickListener(OnClickListener onRetryClickListener) {
this.mOnRetryClickListener = onRetryClickListener;
}
/**
* 显示空视图
*/
public final void showEmpty() {
showEmpty(mEmptyViewResId, DEFAULT_LAYOUT_PARAMS);
}
/**
* 显示空视图
* @param layoutId 自定义布局文件
* @param layoutParams 布局参数
*/
public final void showEmpty(int layoutId, ViewGroup.LayoutParams layoutParams) {
showEmpty(inflateView(layoutId), layoutParams);
}
/**
* 显示空视图
* @param view 自定义视图
* @param layoutParams 布局参数
*/
public final void showEmpty(View view, ViewGroup.LayoutParams layoutParams) {
checkNull(view, "Empty view is null!");
mViewStatus = STATUS_EMPTY;
if (null == mEmptyView) {
mEmptyView = view;
View emptyRetryView = mEmptyView.findViewById(R.id.empty_retry_view);
if (null != mOnRetryClickListener && null != emptyRetryView) {
emptyRetryView.setOnClickListener(mOnRetryClickListener);
}
mOtherIds.add(mEmptyView.getId());
addView(mEmptyView, 0, layoutParams);
}
showViewById(mEmptyView.getId());
}
/**
* 显示错误视图
*/
public final void showError() {
showError(mErrorViewResId, DEFAULT_LAYOUT_PARAMS);
}
/**
* 显示错误视图
* @param layoutId 自定义布局文件
* @param layoutParams 布局参数
*/
public final void showError(int layoutId, ViewGroup.LayoutParams layoutParams) {
showError(inflateView(layoutId), layoutParams);
}
/**
* 显示错误视图
* @param view 自定义视图
* @param layoutParams 布局参数
*/
public final void showError(View view, ViewGroup.LayoutParams layoutParams) {
checkNull(view, "Error view is null!");
mViewStatus = STATUS_ERROR;
if (null == mErrorView) {
mErrorView = view;
View errorRetryView = mErrorView.findViewById(R.id.error_retry_view);
if (null != mOnRetryClickListener && null != errorRetryView) {
errorRetryView.setOnClickListener(mOnRetryClickListener);
}
mOtherIds.add(mErrorView.getId());
addView(mErrorView, 0, layoutParams);
}
showViewById(mErrorView.getId());
}
/**
* 显示加载中视图
*/
public final void showLoading() {
showLoading(mLoadingViewResId, DEFAULT_LAYOUT_PARAMS);
}
/**
* 显示加载中视图
* @param layoutId 自定义布局文件
* @param layoutParams 布局参数
*/
public final void showLoading(int layoutId, ViewGroup.LayoutParams layoutParams) {
showLoading(inflateView(layoutId), layoutParams);
}
/**
* 显示加载中视图
* @param view 自定义视图
* @param layoutParams 布局参数
*/
public final void showLoading(View view, ViewGroup.LayoutParams layoutParams) {
checkNull(view, "Loading view is null!");
mViewStatus = STATUS_LOADING;
if (null == mLoadingView) {
mLoadingView = view;
mOtherIds.add(mLoadingView.getId());
addView(mLoadingView, 0, layoutParams);
}
showViewById(mLoadingView.getId());
}
/**
* 显示无网络视图
*/
public final void showNoNetwork() {
showNoNetwork(mNoNetworkViewResId, DEFAULT_LAYOUT_PARAMS);
}
/**
* 显示无网络视图
* @param layoutId 自定义布局文件
* @param layoutParams 布局参数
*/
public final void showNoNetwork(int layoutId, ViewGroup.LayoutParams layoutParams) {
showNoNetwork(inflateView(layoutId), layoutParams);
}
/**
* 显示无网络视图
* @param view 自定义视图
* @param layoutParams 布局参数
*/
public final void showNoNetwork(View view, ViewGroup.LayoutParams layoutParams) {
checkNull(view, "No network view is null!");
mViewStatus = STATUS_NO_NETWORK;
if (null == mNoNetworkView) {
mNoNetworkView = view;
View noNetworkRetryView = mNoNetworkView.findViewById(R.id.no_network_retry_view);
if (null != mOnRetryClickListener && null != noNetworkRetryView) {
noNetworkRetryView.setOnClickListener(mOnRetryClickListener);
}
mOtherIds.add(mNoNetworkView.getId());
addView(mNoNetworkView, 0, layoutParams);
}
showViewById(mNoNetworkView.getId());
}
/**
* 显示内容视图
*/
public final void showContent() {
mViewStatus = STATUS_CONTENT;
if (null == mContentView && mContentViewResId != NULL_RESOURCE_ID) {
mContentView = mInflater.inflate(mContentViewResId, null);
addView(mContentView, 0, DEFAULT_LAYOUT_PARAMS);
}
showContentView();
}
private void showContentView() {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
view.setVisibility(mOtherIds.contains(view.getId()) ? View.GONE : View.VISIBLE);
}
}
private View inflateView(int layoutId) {
return mInflater.inflate(layoutId, null);
}
private void showViewById(int viewId) {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
view.setVisibility(view.getId() == viewId ? View.VISIBLE : View.GONE);
}
}
private void checkNull(Object object, String hint) {
if (null == object) {
throw new NullPointerException(hint);
}
}
private void clear(View... views) {
if (null == views) {
return;
}
try {
for (View view : views) {
if (null != view) {
removeView(view);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
style="@style/MultipleStatusView.Content"
android:text="@string/empty_view_hint"/>
</RelativeLayout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
style="@style/MultipleStatusView.Content"
android:text="@string/error_view_hint"/>
</RelativeLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ProgressBar
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
</RelativeLayout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
style="@style/MultipleStatusView.Content"
android:text="@string/no_network_view_hint"/>
</RelativeLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MultipleStatusView">
<attr name="loadingView" format="reference"/>
<attr name="errorView" format="reference"/>
<attr name="emptyView" format="reference"/>
<attr name="noNetworkView" format="reference"/>
<attr name="contentView" format="reference"/>
</declare-styleable>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="empty_retry_view" type="id"/>
<item name="error_retry_view" type="id"/>
<item name="no_network_retry_view" type="id"/>
</resources>

View File

@@ -0,0 +1,7 @@
<resources>
<string name="app_name">multiple-status-view</string>
<string name="empty_view_hint">暂无数据</string>
<string name="error_view_hint">加载失败</string>
<string name="no_network_view_hint">网络异常</string>
</resources>

View File

@@ -0,0 +1,11 @@
<resources>
<style name="MultipleStatusView"/>
<style name="MultipleStatusView.Content">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_centerInParent">true</item>
<item name="android:layout_margin">8dp</item>
<item name="android:textColor">#a9b7b7</item>
<item name="android:textSize">16sp</item>
</style>
</resources>