AndroidAndroid 进阶之路Android开发

【 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 额外添加,很安卓!!!

上一篇 下一篇

猜你喜欢

热点阅读