美文网首页程序员
独立于视图的加载控件--让视图更干净

独立于视图的加载控件--让视图更干净

作者: Gavinme | 来源:发表于2018-03-22 14:57 被阅读18次

    项目源码请参考https://github.com/CarryGanLove/LoadingHelper

    背景和问题

    在app后sdk开发过程中,如果有遇到延时任务的时候,往往需要添加一个通用的loading控件用来展示给用户,一来为了提示用户当前有耗时的操作,二来降低用户的等待感提升用户体验。
    所以,一个通用的loading组件就应运而生。
    但似乎并不是所有人都会友好地去开发这样的控件。
    举个栗子,以下是某个项目源码:

    <?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/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/title_bar">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <com.creditapply.custom_view.RoundCornerImageView
                    android:id="@+id/iv_credit_img"
                    android:layout_width="300dp"
                    android:layout_height="185dp"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginBottom="18dp"
                    android:layout_marginLeft="25dp"
                    android:layout_marginRight="25dp"
                    android:layout_marginTop="20dp"
                    android:src="@drawable/card_default" />
    
                <TextView
                    android:id="@+id/tv_credit_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="@dimen/credit_margin_ege"
                    android:maxLines="1"
                    android:text="银行卡名称"
                    android:textColor="@color/black"
                    android:textSize="@dimen/theme_txt_size_17" />
    
    
            </LinearLayout>
    
            <TextView
                android:id="@+id/bottomButton"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:layout_alignParentBottom="true"
                android:background="@drawable/btn_main_blue"
                android:gravity="center"
                android:text="立即申请"
                android:textColor="#ffffff"
                android:textSize="@dimen/theme_txt_size_16"
                android:visibility="visible" />
    
        </RelativeLayout>
    
        <com.app.common.widgets.LoadRalatedView
            android:id="@+id/load_failure_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/title_bar"
            android:layout_centerInParent="true" />
    
    
    </RelativeLayout>
    

    由于视图结构相对简单,所以代码看上去没那么糟糕,很便于阅读。事实真是这样吗?(事实是我删了一堆代码,只留了几个元素测试)
    我们来打开Android studio的priview


    image.png

    几乎什么都看不到,这并不是一种友好的体验。
    1.虽然封装了LoadRalatedView(loading的控件),但是必须要放于顶层,加载时显示,但是把真实视图给遮挡了。
    2.代码的冗余,几乎每个需要网络加载的地方,都需要手动去增加这样的代码。
    3.直接的结果导致开发者不能专注真正的业务视图。

    期望

    我希望开发者能够完成沉浸在业务视图开发中而不是在xml中主动添加一个loadingView。
    基于这个目的,我首先想到是在java层中去动态实例化一个这样的控件,那么我们所要做的就是去选取一个这样的view(命名为contentView,就是被user能看到的view),它能够被控件持有并占据所在的位置,这样可以主动的去展示contentView或者loadingview或者netWorkErroView,甚至还能对这些view做深度的定制。

    基于这个想法可以继续的延伸。大多数情况,给用户展示的这个contentView是固定某个,基本是除了titlebar的部分。这样,我们甚至都不用去主动需找这样的一个锚点用于初始化控件,在基类中就可以初始化控件。
    于是,我们调用的代码应该是这样的:

    
             getLoadingHelper().showLoadingView();//loading
            //执行耗时操作
            JTHttpClient.create()
                    .url(CreditServiceHelper.URL_PREFIX + current_method)
                    .setSecLevel(JtRequest.PRIVATE_CRYPT)
                    .build()
                    .post(NextBeanResult.class)
                    .subscribe(new DisposableSingleObserver<NextBeanResult>() {
                        @Override
                        public void onSuccess(NextBeanResult nextBeanResult) {
                            getLoadingHelper().showContentView();//showContentView
                            mInputLayout.reBuildViews(nextBeanResult);
                           
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            getLoadingHelper().showNetworkError();//showNetworkError
                            UIUtil.INSTANCE.showExceptionMsg(e);
                        }
                    });
    
            
    

    原理和实现

    //todo

    相关文章

      网友评论

        本文标题:独立于视图的加载控件--让视图更干净

        本文链接:https://www.haomeiwen.com/subject/kbqoqftx.html