美文网首页Android开发实用技巧Android技术Android资料
打造简单灵活的支持所有View的Android 空页面及错误页面

打造简单灵活的支持所有View的Android 空页面及错误页面

作者: 全科 | 来源:发表于2016-05-04 16:18 被阅读3546次

    当页面加载数据失败,数据为空,或者数据加载中需要可以操作其他地方,我们应该怎么办?

    体验良好的APP都会做相应的处理。

    1. 比如网络异常,会显示一个网络异常页面,提示用户去检查网络;

    2. 数据为空时,出现一个温馨的空页面,引导用户去创建数据等;

    3. 当数据在加载中时,我想按返回按钮,想切换tab,想做更多的事情时,弹出一个loading就不是那么友好了,直接在页面的内容显示区域显示加载中,问题就解决了。

    这些方法各大app都在使用,但是怎么发开?每一个页面都写一个空页、面错误页面和loading页面吗?那也太恶心了吧。

    下面我们一起打造简单灵活的支持所有View的Android 空页面及错误页面:

    开始之前先看效果:

    打造简单灵活的支持所有View的Android 空页面及错误页面.png

    继承LinearLayout

    public class EmptyLayout extends LinearLayout{
    
    public EmptyLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    }
    
    

    我们需要实现三种不同的页面,所以需要定义三种类型:

    
     /**
         * The empty state
         */
        public final static int TYPE_EMPTY = 1;
        /**
         * The loading state
         */
        public final static int TYPE_LOADING = 2;
        /**
         * The error state
         */
        public final static int TYPE_ERROR = 3;
    
    

    定义操作方法:

    
    /**
         * 展示错误信息
         * @param resId 图片资源id
         * @param text
         */
        public void showError(int resId,String text)
    
    /**
         * 展示空信息
         * @param resId 图片资源id
         * @param text
         */
        public void showEmpty(int resId,String text)
    
    /**
         * 展示加载中
         * @param resId 图片资源id
         * @param text
         */
        public void showLoading(int resId,String text)
    
    /**
         *隐藏EmptyLayout
         */
        public void hide()
    
    

    获得EmptyLayout的子view,方便隐藏或者展示子view(这里的子view 一般用户展示本来的内容)

    /**
         * 获得EmptyLayout的子view
         */
        private void getChildViews(){
            int childCount = getChildCount();
            Log.d("EmptyLayout","ChildCount:"+childCount);
            View view;
            for (int i=0;i<childCount;i++){
                view = getChildAt(i);
                if (isEmptyView(view)){
                    continue;
                }
                childViews.add(view);
            }
        }
    

    判断view 对象是否是EmptyView :

    
    /**
         * 判断view 对象是否是EmptyView
         * @param view
         * @return
         */
        private boolean isEmptyView(View view){
            if ((view == null||mEmptyRelativeLayout == view||view == mLoadingView||view == mEmptyView||view == mErrorView)){
                return true;
            }
            return false;
        }
    

    当数据为空时调用:

    public void showEmpty(){
    
            getChildViews(); //获得除EmptyView的其他子view
            hideChildView(); //把子view隐藏了
            this.mEmptyType = TYPE_EMPTY;
            changeEmptyType();
            
        }
    
    

    其他方法和这个类似,思路很简单,大家可以试试

    使用很简单

    在布局文件里增加:

    <name.quanke.app.libs.emptylayout.EmptyLayout
            android:id="@+id/emptyLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/textHello"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!" />
    
    </name.quanke.app.libs.emptylayout.EmptyLayout>
    

    代码里增加:

    findViewById(R.id.btnLoading).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    emptyLayout.showLoading();
                }
            });
            findViewById(R.id.btnEmpty).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    emptyLayout.showEmpty();
                }
            });
            findViewById(R.id.btnError).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    emptyLayout.showError();
                }
            });
            findViewById(R.id.btnData).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    emptyLayout.hide();
                }
            });
    

    好了,使用起来就这么简单。。。支持所有的view

    源码放在github上:https://github.com/quanke/AndroidEmptyLayout

    欢迎讨论

    全科龙婷▼升职加薪

    image

    相关文章

      网友评论

      • N城渔夫:重点是直接导入就可以使用、感谢github
      • 刚刚了然:用LinearLayout必须要用GONE去隐藏把.这样性能会比较低,一般隐藏是尽量用INVISIBLE
        ,这里用framlayout和INVISIBLE更优雅.
        全科:@刚刚了然 现在有更好的方案了吧,写了很多年了吧
      • 697c21ce5a24:我一直在想怎么做可以侵入性降低,直接代码实现,不需要改xml。在baseactivity中提供能力,改动不影响原有代码,还没想到怎么做
      • 0d8119501ffe:点击重试那个需求 还是是需要自己来手写吗:flushed:
        0d8119501ffe:@依然丶诺随风 使用ButterKnife之后没在正确的地方设置那个方法。。。
        0d8119501ffe:奇怪,emptyLayout.setErrorButtonClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        Log.e("TAG", "点击重试了!!!");
        }
        });
        为什么我的不显示这个button。。
      • 610fcc1f522b:每个界面你都要这样写吗?
        610fcc1f522b:@quanke 你可以试试,有空我也试试
        全科:@koot 也可以不这样,如果需要只是内容区域需要loading,那就定义好规则,每次设置内容的view的时候,先loading,可以交给框架处理,我有时间写一下这个,一两句我也表达不好,但是这种方法似乎没有写xml灵活
        SearchSunny:@koot 每个页面XML都这么写确实繁琐,有没有更好的处理方法?
      • 127337a53bc2:不错不错,我也自己研究过这个问题,解决方法也差不多
      • 088bceee8087:就扩展性而言framelayout更合适
        全科:@喜欢延安的小雨 有道理,你可以fork项目
      • sendtion:学习了,体验很重要~

      本文标题:打造简单灵活的支持所有View的Android 空页面及错误页面

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