美文网首页Android代码封装Android知识Android开发
android简易封装出错时默认展示页

android简易封装出错时默认展示页

作者: SilenceMan | 来源:发表于2017-06-14 14:50 被阅读360次

    项目中有时候会经常遇到加载页面出错,加载页面没有数据,没有网络等等情况。这些情况需要一个特别的展示来告知用户,并且提供点击事件来重新加载等等情况。一般情况下我就直接在布局上面盖一层布局用来展示这种情况,如果只有一个页面或者极少页面需要这么做,也到简单。但是如果大量页面都需要,那我们的xml就难免会点的层级过多,不便于阅读。也有可能在preview的时候看不清我们真正需要展示的页面结构等等,基于此,本着大家一起学习的态度,我写了一个简单的代码用以封装这种情形。

    其中的原理可以先阅读鸿洋大神的此篇博客 Android 源码解析 之 setContentView

    private FrameLayout mFrameLayout; //此处即为android中我们setContentView时根布局的父布局
    private View mDefaultView; //这是我们加载页面出错,或者没有网络时的默认布局
    private View mContentView;//这是我们自己真正的业务逻辑的布局
    
    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        mFrameLayout = (FrameLayout) findViewById(android.R.id.content);
            
        mDefaultView = LayoutInflater.from(activity).inflate(R.layout.default_layout, mFrameLayout, false);//这个defaul_layout是统一的错误页面展示布局
            
        mContentView = LayoutInflater.from(activity).inflate(layoutResID, mFrameLayout, false);//这个layoutResId就是我们需要的业务逻辑布局了
        
        //将出错页面和逻辑页面分别加载到mFramLayout中去,并隐藏出错页面
        mFrameLayout.addView(mContentView);
        mFrameLayout.addView(mDefaultView);
        mDefaultView.setVisibility(View.GONE);
    }
    
    /**
    *
    **
    /
    protected void showDefaultView() {
        mDefaultView.setVisibility(View.VISIBLE);
        mContentView.setVisibility(View.GONE);
    }
    
    protected void hideDefaultView() {
        mDefaultView.setVisibility(View.GONE);
        mContentView.setVisibility(View.VISIBLE);
    }
    
    

    R.layout.default_layout的布局文件如下

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/default_image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_luncher" />
    
        <TextView
            android:id="@+id/default_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="这个地方空空如也" />
    
    </LinearLayout>
    

    那这个默认布局,我如果不一样了?比如网络加载出错的图片,和没有获取到内容的图片等等,我该如何修改呢?

        private ImageView defaultImage;
        private TextView defaultText;
        
        
        /**
         * @param drawableResID 需要更换的图标
         * @param text          需要更换的问题
         * @param listener      图标的点击事件
         *
         * 你可以只放一个drawableResID,那么此处的textView将会被隐藏,你可以选择将image和文字切成一张图,这样就简单多了。比较懒的方法
         */
        protected void initDefaultView(@DrawableRes int drawableResID, String text, View.OnClickListener listener) {
            defaultImage = (ImageView) findViewById(R.id.default_image_view);
            defaultText = (TextView) findViewById(R.id.default_text_view);
    
            if (drawableResID <= 0) {
                defaultImage.setVisibility(View.GONE);
            } else {
                defaultImage.setVisibility(View.VISIBLE);
                defaultImage.setImageResource(drawableResID);
            }
    
            if (TextUtils.isEmpty(text)) {
                defaultText.setVisibility(View.GONE);
            } else {
                defaultText.setVisibility(View.VISIBLE);
                defaultText.setText(text);
            }
    
            if (listener != null) {
                mDefaultView.setOnClickListener(listener);
            }
        }
    

    如果项目中有的页面出错页面比较简单,有的比较复杂,或者布局样式根本就和默认的布局已经千差万别了,咋办?

    那我们将上面的代码改一下,我们先定义一个方法,默认返回空

        protected View useCustomLayout() {
            return null;
        }
    
        @Override
        public void setContentView(@LayoutRes int layoutResID) {
            mFrameLayout = (FrameLayout) findViewById(android.R.id.content);
            //此处我们先判断是否重写了useCustomLayout这个方法,如果重写了,那么就将defaultView赋值为重写返回的view即可
            if (useCustomLayout() == null) {
                mDefaultView = LayoutInflater.from(activity).inflate(R.layout.default_layout, mFrameLayout, false);
            } else {
                mDefaultView = useCustomLayout();
            }
    
            mContentView = LayoutInflater.from(activity).inflate(layoutResID, mFrameLayout, false);
          
            mFrameLayout.addView(mDefaultView);
            mFrameLayout.addView(mContentView);
            mDefaultView.setVisibility(View.GONE);
           
        }
    

    完整代码如下

    import android.support.annotation.LayoutRes;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.text.TextUtils;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import minihou.net.library.R;
    
    /**
     * Created by monking-macbook
     * on 2017/6/13
     * in MiniHouBaseCore
     * description: use a dialog to introduce this class
     */
    
    public class MiniHouBaseActivity extends AppCompatActivity {
    
        protected Activity activity;
    
        private FrameLayout mFrameLayout;
    
        private View mDefaultView;
        private View mContentView;
        private ImageView defaultImage;
        private TextView defaultText;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            activity = this;
        }
    
        @Override
        public void setContentView(@LayoutRes int layoutResID) {
            mFrameLayout = (FrameLayout) findViewById(android.R.id.content);
            if (useCustomLayout() == null) {
                mDefaultView = LayoutInflater.from(activity).inflate(R.layout.default_layout, mFrameLayout, false);
            } else {
                mDefaultView = useCustomLayout();
            }
    
            mContentView = LayoutInflater.from(activity).inflate(layoutResID, mFrameLayout, false);
            mFrameLayout.addView(mDefaultView);
            mFrameLayout.addView(mContentView);
            mDefaultView.setVisibility(View.GONE);
        }
    
        protected View useCustomLayout() {
            return null;
        }
    
    
        /**
         * @param drawableResID 需要更换的图标
         * @param text          需要更换的问题
         * @param listener      图标的点击事件
         */
        protected void initDefaultView(@DrawableRes int drawableResID, String text, View.OnClickListener listener) {
            if (useCustomLayout() != null) {
                    return;
            }
            defaultImage = (ImageView) findViewById(R.id.default_image_view);
            defaultText = (TextView) findViewById(R.id.default_text_view);
    
            if (drawableResID <= 0) {
                defaultImage.setVisibility(View.GONE);
            } else {
                defaultImage.setVisibility(View.VISIBLE);
                defaultImage.setImageResource(drawableResID);
            }
    
            if (TextUtils.isEmpty(text)) {
                defaultText.setVisibility(View.GONE);
            } else {
                defaultText.setVisibility(View.VISIBLE);
                defaultText.setText(text);
            }
    
            if (listener != null) {
                defaultImage.setOnClickListener(listener);
            }
        }
    
        /**
         * 如果加载出错show出这个默认布局并隐藏我们的业务逻辑布局
         */
        protected void showDefaultView() {
            mDefaultView.setVisibility(View.VISIBLE);
            mContentView.setVisibility(View.GONE);
        }
    
        /**
         * 如果没有出错,就展示我们的业务逻辑布局,并隐藏出错的布局。
         */
        protected void hideDefaultView() {
            mDefaultView.setVisibility(View.GONE);
            mContentView.setVisibility(View.VISIBLE);
        }
    
    }
    

    使用方法

    首先创建Activity继承上述Activity,然后。。。

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //千万注意得先调用setContentView
            if(true){//加载数据没出错,页面数据不为空等等
                hideDefaultView();
            }else{
                showDefaultView();
            }
        }
    

    如果需要更改图标和文字,添加点击事件

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initDefaultView(R.drawable.new_icon, "此处空空如也", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "点击页面重试", Toast.LENGTH_SHORT).show();
                }
            });
        }       
    

    如果需要自己定义布局

        @Override
        protected View useCustomLayout() {
            View view=LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_layout, null);
            return view;
        }
    

    好了,有需要的同学可以去试试哦,如果有改进可以在下面留言给我。

    相关文章

      网友评论

      本文标题:android简易封装出错时默认展示页

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