android 載入佈局狀態封裝
阿新 • • 發佈:2019-02-16
我們經常會碰見 正在載入中,加載出錯, “暫無商品”等一系列的相似的佈局,因為我們有很多請求網路資料的頁面,我們不可能每一個頁面都寫幾個“正在載入中”等佈局吧,這時候將這些狀態的佈局封裝在一起就很有必要了。我們可以將這些封裝為一個自定佈局,然後每次操作該自定義類的方法就行了。
首先一般來說,從伺服器拉去資料之前都是“正在載入”頁面, 載入成功之後“正在載入”頁面消失,展示資料;如果載入失敗,就展示“加載出錯”頁面,同樣的“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 想使用這種封裝的可以參考下