美文网首页
android简易封装出错时默认展示页

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

作者: 方_f666 | 来源:发表于2019-11-26 13:45 被阅读0次

<meta charset="utf-8">

项目中有时候会经常遇到加载页面出错,加载页面没有数据,没有网络等等情况。这些情况需要一个特别的展示来告知用户,并且提供点击事件来重新加载等等情况。一般情况下我就直接在布局上面盖一层布局用来展示这种情况,如果只有一个页面或者极少页面需要这么做,也到简单。但是如果大量页面都需要,那我们的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/jlvewctx.html