方法一:UILoader
package cool.hyz.xujiayi.views;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import cool.hyz.xujiayi.R;
import cool.hyz.xujiayi.base.BaseApplication;
import cool.hyz.xujiayi.components.LoopTextView;
public abstract class UILoader extends FrameLayout {
private static final String TAG = "UILoader";
private View mLoadingView;
private View mSuccessView;
private View mNetworkErrorView;
private View mEmptyView;
public void setShow(boolean show) {
isShow = show;
updateLoadingLoopTextState();
}
private OnRetryClickListener mOnRetryClickListener = null;
public enum UIStatus {
LOADING, SUCCESS, NETWORK_ERROR, EMPTY, NONE
}
public UIStatus mCurrentUIStatus = UIStatus.NONE;
public UILoader(@NonNull Context context) {
super(context);
}
public UILoader(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public UILoader(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
public void updateUIStatus(UIStatus status) {
mCurrentUIStatus = status;
BaseApplication.getHandler().post(this::switchUIByCurrentStatus);
}
private void initView() {
switchUIByCurrentStatus();
}
private void switchUIByCurrentStatus() {
if (mLoadingView == null) {
mLoadingView = getLoadingView();
addView(mLoadingView);
}
mLoadingView.setVisibility(mCurrentUIStatus == UIStatus.LOADING ? VISIBLE : GONE);
if (mSuccessView == null) {
mSuccessView = getSuccessView(this);
if (mSuccessView.getParent() instanceof ViewGroup) {
((ViewGroup) mSuccessView.getParent()).removeView(mSuccessView);
}
addView(mSuccessView);
}
mSuccessView.setVisibility(mCurrentUIStatus == UIStatus.SUCCESS ? VISIBLE : GONE);
if (mNetworkErrorView == null) {
mNetworkErrorView = getNetworkErrorView();
addView(mNetworkErrorView);
}
mNetworkErrorView.setVisibility(mCurrentUIStatus == UIStatus.NETWORK_ERROR ? VISIBLE : GONE);
if (mEmptyView == null) {
mEmptyView = getEmptyView();
addView(mEmptyView);
}
mEmptyView.setVisibility(mCurrentUIStatus == UIStatus.EMPTY ? VISIBLE : GONE);
}
private View getLoadingView() {
View loading = LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_loading,
return loading;
}
public abstract View getSuccessView(ViewGroup container);
private View getNetworkErrorView() {
View networkErrorView = LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_network_error, this, false);
networkErrorView.setOnClickListener((view) -> {
if (mOnRetryClickListener != null) {
mOnRetryClickListener.onClickToRetry();
}
});
return networkErrorView;
}
private View getEmptyView() {
return LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_empty, this, false);
}
public void setOnRetryClickListener(OnRetryClickListener listener) {
mOnRetryClickListener = listener;
}
public interface OnRetryClickListener {
void onClickToRetry();
}
}
java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/page_background"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:src="@drawable/ic_loading"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/loading_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="正在拼命加载中..." />
</LinearLayout>
xml
- ui_loader_network_error.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/page_background"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:src="@drawable/ic_network_error"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="网络不佳...点击重试" />
</LinearLayout>
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/page_background"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:src="@drawable/ic_empty"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="数据不翼而飞..." />
</LinearLayout>
xml
package cool.hyz.xujiayi.views.home;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.lifecycle.ViewModelProvider;
import java.util.List;
import cool.hyz.xujiayi.R;
import cool.hyz.xujiayi.base.BaseFragment;
import cool.hyz.xujiayi.views.UILoader;
public class HomeFragment extends Fragment {
public static final String TAG = "HomeFragment";
private View mRoot;
private HomeViewModel mHomeViewModel;
private static UILoader sUILoader;
public HomeFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (sUILoader != null) {
return sUILoader;
}
sUILoader = new UILoader(requireContext()) {
@Override
public View getSuccessView(ViewGroup container) {
return createSuccess(inflater, container);
}
};
sUILoader.setOnRetryClickListener(() -> {
});
return sUILoader;
}
@Override
public View createSuccess(LayoutInflater inflater, ViewGroup container) {
Log.d(TAG, "createSuccess: ...");
mHomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
mRoot = inflater.inflate(R.layout.fragment_home, container, false);
sUILoader.updateUIStatus(UILoader.UIStatus.SUCCESS);
return mRoot;
}
@Override
public void onResume() {
super.onResume();
sUILoader.updateUIStatus(UILoader.UIStatus.LOADING);
}
}
java
方法二:BaseFragment
package cool.hyz.xujiayi.base;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import cool.hyz.xujiayi.R;
import cool.hyz.xujiayi.components.LoopTextView;
public abstract class BaseFragment extends Fragment {
public static final String TAG = "BaseFragment";
private View mRoot;
private FrameLayout mBaseContainer;
private View mLoadingView;
private View mSuccessView;
private View mNetworkErrorView;
private View mEmptyView;
protected boolean isLoaded = false;
private OnRetryClickListener mOnRetryClickListener = null;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.base_fragment_layout, container, false);
mBaseContainer = mRoot.findViewById(R.id.base_container);
loadStateView(inflater, container);
return mRoot;
}
public enum UIStatus {
LOADING, SUCCESS, NETWORK_ERROR, EMPTY, NONE
}
public UIStatus mCurrentUIStatus = UIStatus.NONE;
private void loadStateView(LayoutInflater inflater, ViewGroup container) {
mLoadingView = createLoadingView(container);
mBaseContainer.addView(mLoadingView);
mLoadingView.setVisibility(mCurrentUIStatus == UIStatus.LOADING ? VISIBLE : GONE);
updateLoadingLoopTextState();
mSuccessView = createSuccessView(inflater, container);
if (mSuccessView.getParent() instanceof ViewGroup) {
((ViewGroup) mSuccessView.getParent()).removeView(mSuccessView);
}
mBaseContainer.addView(mSuccessView);
mSuccessView.setVisibility(mCurrentUIStatus == UIStatus.SUCCESS ? VISIBLE : GONE);
mNetworkErrorView = createNetworkErrorView(container);
mBaseContainer.addView(mNetworkErrorView);
mNetworkErrorView.setVisibility(mCurrentUIStatus == UIStatus.NETWORK_ERROR ? VISIBLE : GONE);
mEmptyView = createEmptyView(container);
mBaseContainer.addView(mEmptyView);
mEmptyView.setVisibility(mCurrentUIStatus == UIStatus.EMPTY ? VISIBLE : GONE);
}
public void updateUIStatus(UIStatus status) {
mCurrentUIStatus = status;
mLoadingView.setVisibility(mCurrentUIStatus == UIStatus.LOADING ? VISIBLE : GONE);
updateLoadingLoopTextState();
mSuccessView.setVisibility(mCurrentUIStatus == UIStatus.SUCCESS ? VISIBLE : GONE);
mNetworkErrorView.setVisibility(mCurrentUIStatus == UIStatus.NETWORK_ERROR ? VISIBLE : GONE);
mEmptyView.setVisibility(mCurrentUIStatus == UIStatus.EMPTY ? VISIBLE : GONE);
}
private void updateLoadingLoopTextState() {
if (mLoadingView != null) {
LoopTextView loopTextView = mLoadingView.findViewById(R.id.loading_title);
if (mCurrentUIStatus == UIStatus.LOADING && isShow) loopTextView.startLoop();
else loopTextView.stopLoop();
}
}
private View createLoadingView(ViewGroup container) {
View loading = LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_loading, container, false);
return loading;
}
public abstract View createSuccessView(LayoutInflater inflater, ViewGroup container);
private View createNetworkErrorView(ViewGroup container) {
View networkErrorView = LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_network_error, container, false);
networkErrorView.setOnClickListener((view) -> {
if (mOnRetryClickListener != null) {
mOnRetryClickListener.onClickToRetry();
}
});
return networkErrorView;
}
private View createEmptyView(ViewGroup container) {
return LayoutInflater.from(getContext()).inflate(R.layout.ui_loader_empty, container, false);
}
public void setOnRetryClickListener(OnRetryClickListener listener) {
mOnRetryClickListener = listener;
}
public interface OnRetryClickListener {
void onClickToRetry();
}
}
java
package cool.hyz.xujiayi.views.home;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.lifecycle.ViewModelProvider;
import java.util.List;
import cool.hyz.xujiayi.R;
import cool.hyz.xujiayi.base.BaseFragment;
public class HomeFragment extends BaseFragment{
public static final String TAG = "HomeFragment";
private View mRoot;
private HomeViewModel mHomeViewModel;
public HomeFragment() {
}
@Override
public View createSuccessView(LayoutInflater inflater, ViewGroup container) {
Log.d(TAG, "createSuccessView: ...");
mHomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
mRoot = inflater.inflate(R.layout.fragment_home, container, false);
mHomeViewModel.loadData().observe(getViewLifecycleOwner(), this::setData);
return mRoot;
}
private void setData(String data){
Log.d(TAG, "setData: "+data);
updateUIStatus(UIStatus.SUCCESS);
}
}
java
package cool.hyz.xujiayi.views.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
public class HomeViewModel extends ViewModel {
public HomeViewModel() {
}
public LiveData<String> loadData(){
MutableLiveData<String> data = new MutableLiveData<>();
data.setValue("加载成功...");
return data;
}
}
java