【 Android 】打造 Android 原生 Loading
2017-09-25 本文已影响287人
Tyhoo_Wu
说到 Loading,网上一搜示例一大堆,但是我觉得都不是很安卓,那就跟着我一起打造安卓原生 Loading 。
示例 GIF :
Loading to Content.gif Error to Loading to Content.gif
Loading 用得最多的像
① 网络请求数据
② 增删改查数据
③ 数据读写等
本示例分四部分:
① Loading
② Loading 到 显示数据
③ 加载数据失败,显示错误提示
④ 再次加载 到 显示数据
从上面四部分我们可以看出,有相似的部分,那就把他们做成一个共通的 View 来进行使用(很简单的哦~)。
首先是自定义布局:
<?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">
<RelativeLayout
android:id="@+id/rl_tv_failed"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:visibility="gone">
<TextView
android:id="@+id/tv_failed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="加载失败,点击重试"
android:textColor="@android:color/darker_gray"
android:textSize="20sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_progress_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:visibility="visible">
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
</RelativeLayout>
自定义布局分为:显示 ProgressBar 和 加载失败时的提示。
封装一个 LoadingView 当作布局使用:
public class LoadingView extends RelativeLayout {
private RelativeLayout mRelativeLayoutLoading, mRelativeLayoutFailed;
private LoadingView.LoadingViewListener mListener;
public void setListener(LoadingViewListener listener) {
this.mListener = listener;
}
public LoadingView(Context context) {
super(context);
initView(context);
}
public LoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.view_loading, this);
mRelativeLayoutLoading = view.findViewById(R.id.rl_progress_bar);
mRelativeLayoutFailed = view.findViewById(R.id.rl_tv_failed);
mRelativeLayoutFailed.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// 加载失败,点击重试
mRelativeLayoutLoading.setVisibility(View.VISIBLE);
mRelativeLayoutFailed.setVisibility(View.GONE);
mListener.onFailedClickListener();
}
});
}
/**
* 显示加载过程中的状态
*/
public void showLoading() {
mRelativeLayoutLoading.setVisibility(View.VISIBLE);
mRelativeLayoutFailed.setVisibility(View.GONE);
}
/**
* 显示加载完成的状态
*/
public void showContentView() {
mRelativeLayoutLoading.setVisibility(View.GONE);
mRelativeLayoutFailed.setVisibility(View.GONE);
}
/**
* 显示加载失败的状态
*/
public void showFailed() {
mRelativeLayoutLoading.setVisibility(View.GONE);
mRelativeLayoutFailed.setVisibility(View.VISIBLE);
}
public interface LoadingViewListener {
void onFailedClickListener();
}
}
是不是很简单,对外暴露三个方法:
① 显示加载过程中的状态
② 显示加载完成的状态
③ 显示加载失败的状态
简单使用(进行一次网络请求的 Loading 使用):
以 网络请求框架 —— Retrofit http://www.jianshu.com/p/c99dbf612740 这篇文章的代码为 Base 做简单演示。
主布局最外层使用 RelativeLayout 把 自定义 View 包裹起来
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
...
<com.tnnowu.retrofit2sample.LoadingView
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
主类里面调用 Loading 相应的方法:
public class MainActivity extends AppCompatActivity implements LoadingView.LoadingViewListener {
private static final String TAG = MainActivity.class.getSimpleName();
private LoadingView mLoadingView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 本示例是在界面一开始就要调用 Loading ,所以在 onCreate 里面做 Loading 加载,根据项目实际情况在适当的位置进行调用。
mLoadingView = (LoadingView) findViewById(R.id.loading);
mLoadingView.setListener(this);
mLoadingView.showLoading();
// 加载数据
initData();
}
private void initData() {
// Create a very simple REST adapter which points the GitHub API.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
// Create an instance of our GitHub API interface.
MainService service = retrofit.create(MainService.class);
// Create a call instance for looking up Retrofit contributors.
Call<List<Contributor>> call = service.getCall();
Log.d(TAG, "main: " + call);
call.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
if (response.isSuccessful()) {
// 网络请求数据加载成功 Loading 页面关闭,同时显示数据内容的 View
mLoadingView.showContentView();
Log.d(TAG, "onResponse: " + "isSuccessful");
mList = response.body();
Log.d(TAG, "onResponse: " + "list" + mList);
if (mList != null && mList.size() > 0) {
mAdapter.setData(mList);
}
}
}
@Override
public void onFailure(Call<List<Contributor>> call, Throwable t) {
Log.d(TAG, "onFailure: ");
// 网络请求数据失败,显示错误提示
mLoadingView.showFailed();
}
});
}
@Override
public void onFailedClickListener() {
// 当我们解决网络问题之后,想重新加载数据,就在这里,再重新执行一次网络请求。
initData();
}
}
以上就是 打造 Android 原生 Loading 的全部内容,0 额外添加,很安卓!!!