android 加载布局状态封装

来源:互联网 发布:excel如何合计数据 编辑:程序博客网 时间:2024/05/20 19:29

我们经常会碰见 正在加载中,加载出错, “暂无商品”等一系列的相似的布局,因为我们有很多请求网络数据的页面,我们不可能每一个页面都写几个“正在加载中”等布局吧,这时候将这些状态的布局封装在一起就很有必要了。我们可以将这些封装为一个自定布局,然后每次操作该自定义类的方法就行了。
首先一般来说,从服务器拉去数据之前都是“正在加载”页面, 加载成功之后“正在加载”页面消失,展示数据;如果加载失败,就展示“加载出错”页面,同样的“z正在加载”消失; 同理 数据为null的话,也是这样。如下图所示:
这里写图片描述
其实这只是一种代码设计模式,有这种思想就行,实现起来千变万化的。

总体思想就是:自定义FrameLayout ,然后将这FrameLayout中有三个子view,分别是:展示数据的view,加载失败的view, 正在加载的view,数据为null的view; 其实展示数据的view是一直VISIBLE的,切记:其他三个view都要设置为match_parent,然后父布局都要设置color ;

比如数据为null的布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:background="@android:color/white">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="30sp"        android:text="暂无数据!"/></LinearLayout>

父布局是match——parent 然后也设置了颜色;

在声明SynExceptionLayout 的XML中,要如下声明:

<?xml version="1.0" encoding="utf-8"?><com.app.test.testerrorproject.SynExceptionLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.app.test.testerrorproject.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@color/colorPrimary"        android:gravity="center">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="有数据"            android:textSize="30sp"            android:textColor="@color/colorAccent" />    </LinearLayout></com.app.test.testerrorproject.SynExceptionLayout>

可以看到SynExceptionLayout 是在最外层的,而添加的第一个view就是LinearLayout。

看下源码吧

package com.app.test.testerrorproject;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.widget.FrameLayout;import android.widget.LinearLayout;/** * Created by ${liumengqiang} on 2017/7/17. */public class SynExceptionLayout extends FrameLayout {    /**     * 一般的执行顺序是:网络访问前 loadShow(), 然后加载成功之后,successShow();     * 如果加载出错的话,errorShow();     * 如果加载数据为null的话,emptyShow();     * 一般来说使用emptyShow(int res),即自定义布局     */    private LinearLayout emptyLinearLayout;//数据位null时,应该显示的布局    private LinearLayout errorLinearLayout;//数据加载出错时,应该显示的布局    private LinearLayout loadLinearLayout;//正在加载时,应该显示的布局    public static final int EMPTY_INT = 0;//回调标记:数据为null    public static final int ERROR_INT = 1;//回调标记:数据出错    public static final int LOAD_INT = 2;//回调标记:数据正在加载    private OnSynExceptionListaner onSynExceptionListaner;    public OnSynExceptionListaner getOnSynExceptionListaner() {        return onSynExceptionListaner;    }    public void setOnSynExceptionListaner(OnSynExceptionListaner onSynExceptionListaner) {        this.onSynExceptionListaner = onSynExceptionListaner;    }    public SynExceptionLayout(Context context) {        super(context);    }    public SynExceptionLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }    public SynExceptionLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    /**     * 加载为null     */    public void emptyShow(){//默认加载        empty(R.layout.empty_layout);    }    public void emptyShow(int res){//指定加载布局        empty(res);    }    public void empty(int res){        if(emptyLinearLayout == null){            emptyLinearLayout = (LinearLayout) LayoutInflater.from(getContext())                    .inflate(res, this,false);            emptyLinearLayout.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    onSynExceptionListaner.onSynxceptionListener(EMPTY_INT);                }            });        }        if(errorLinearLayout == null){            errorLinearLayout.setVisibility(View.GONE);        }        if(loadLinearLayout == null){            loadLinearLayout.setVisibility(View.GONE);        }        /**         * indexOfChild(View view) 方法返回该view在frameLayout中的位置索引         * 不在里面时,返回 -1;         *         * addView(View view) 将view添加到frameLayout中         */        if(indexOfChild(emptyLinearLayout) == -1){            addView(emptyLinearLayout);            emptyLinearLayout.setVisibility(View.VISIBLE);        }else{            emptyLinearLayout.setVisibility(View.VISIBLE);        }    }    /**     * 加载出错     */    public void errorShow(){        error(R.layout.error_layout);    }    public void errorShow(int res){        error(res);    }    private void error(int res){        if(errorLinearLayout == null){            errorLinearLayout = (LinearLayout) LayoutInflater.from(getContext())                    .inflate(res, this,false);            errorLinearLayout.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    onSynExceptionListaner.onSynxceptionListener(ERROR_INT);                }            });        }        if(loadLinearLayout != null){            loadLinearLayout.setVisibility(View.GONE);        }        if(emptyLinearLayout != null){            emptyLinearLayout.setVisibility(View.GONE);        }        if(indexOfChild(errorLinearLayout) == -1){            addView(errorLinearLayout);            errorLinearLayout.setVisibility(VISIBLE);        }else{            errorLinearLayout.setVisibility(VISIBLE);        }    }    /**     * 正在加载     */    public void loadShow(){        load(R.layout.load_layout);    }    public void loadShow(int res){        load(res);    }    private void load(int res){        if(loadLinearLayout == null){            loadLinearLayout = (LinearLayout) LayoutInflater.from(getContext())                    .inflate(res, this, false);            loadLinearLayout.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    onSynExceptionListaner.onSynxceptionListener(LOAD_INT);                }            });        }        if(errorLinearLayout != null){            errorLinearLayout.setVisibility(View.GONE);        }        if(emptyLinearLayout  != null){            emptyLinearLayout.setVisibility(View.GONE);        }        if(indexOfChild(loadLinearLayout) == -1){            addView(loadLinearLayout);            loadLinearLayout.setVisibility(View.VISIBLE);        }else{            loadLinearLayout.setVisibility(View.VISIBLE);        }    }    /**     *成功时,将三个布局都设置为GONE     */    public void successShow(){        if(emptyLinearLayout != null){            emptyLinearLayout.setVisibility(View.GONE);        }        if(errorLinearLayout != null){            errorLinearLayout.setVisibility(View.GONE);        }        if(loadLinearLayout != null){            loadLinearLayout.setVisibility(View.GONE);        }    }    /**     * 回调接口     */    public interface OnSynExceptionListaner{        void onSynxceptionListener(int flug);    }}

附上操作SynExceptionLayout 的demo 想使用这种封装的可以参考下

http://download.csdn.net/detail/lmq121210/9901548

原创粉丝点击