1. 程式人生 > >Android自定義view實現載入中、載入失敗、無資料

Android自定義view實現載入中、載入失敗、無資料

一、概述

Android中經常在有的app中可以見到“載入中”並不是以彈出對話方塊的形式顯示的,而是佔用整個螢幕,如果載入失敗就會出現載入失敗頁面,點選載入失敗頁面中任意區域,都可以重新載入。今天就和大家一起學習如何通過自定義view的方式實現載入中、載入失敗、無資料的效果。
實現效果圖

二、實現程式碼

自定義屬性檔案

<declare-styleable name="LoadingLayout">
        <attr name="loadingView" format="reference" />
        <attr name="stateView"
format="reference" />
<attr name="emptyView" format="reference" /> </declare-styleable>

自定義view:LoadingLayout.java

package com.czhappy.effectdemo.loadinglayout;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import
android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.czhappy.effectdemo.R; public class LoadingLayout extends FrameLayout { /** * 空資料View */ private int mEmptyView; /** * 狀態View */
private int mStateView; /** * 載入View */ private int mLoadingView; public LoadingLayout(Context context) { this(context, null); } public LoadingLayout(Context context, AttributeSet attrs) { this(context, attrs, -1); } public LoadingLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LoadingLayout, 0, 0); try { mStateView = a.getResourceId(R.styleable.LoadingLayout_stateView, R.layout.loadstate_layout); mLoadingView = a.getResourceId(R.styleable.LoadingLayout_loadingView, R.layout.loading_layout); mEmptyView = a.getResourceId(R.styleable.LoadingLayout_emptyView, R.layout.empty_layout); LayoutInflater inflater = LayoutInflater.from(getContext()); inflater.inflate(mStateView, this, true); inflater.inflate(mLoadingView, this, true); inflater.inflate(mEmptyView, this, true); } finally { a.recycle(); } } /** * 佈局載入完成後隱藏所有View */ @Override protected void onFinishInflate() { super.onFinishInflate(); for (int i = 0; i < getChildCount() - 1; i++) { getChildAt(i).setVisibility(GONE); } } /** * 設定Empty點選事件 * @param listener */ public void setEmptyClickListener(final OnClickListener listener) { if( listener!=null ) findViewById(R.id.state_retry2).setOnClickListener(listener); } /** * 設定State點選事件 * @param listener */ public void setStateClickListener( OnClickListener listener ){ if(listener!=null) findViewById(R.id.state_retry).setOnClickListener(listener); } /** * 設定自定義佈局的點選事件 * @param resoureId * @param listener */ public void setViewOncClickListener(int resoureId,OnClickListener listener) { findViewById(resoureId).setOnClickListener(listener); } /** * 設定自定義佈局的view文字 * @param resoureId * @param text */ public void setViewText(int resoureId,String text){ ((TextView)findViewById(resoureId)).setText(text); } /** * 設定自定義佈局的image * @param resoureId * @param img */ public void setViewImage(int resoureId,int img ){ ((ImageView)findViewById(resoureId)).setImageResource(img); } /** * State View */ public void showState() { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 0) { child.setVisibility(VISIBLE); } else { child.setVisibility(GONE); } } } /** * Empty view */ public void showEmpty() { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 2) { child.setVisibility(VISIBLE); } else { child.setVisibility(GONE); } } } /** * Loading view */ public void showLoading() { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 1) { child.setVisibility(VISIBLE); } else { child.setVisibility(GONE); } } } /** * * @param text */ public void showLoading(String text) { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 1) { child.setVisibility(VISIBLE); ((TextView) child.findViewById(R.id.loading_text)).setText(text + ""); } else { child.setVisibility(GONE); } } } /** * Empty view * * @param text */ public void showEmpty(String text) { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 2) { child.setVisibility(VISIBLE); ((TextView) child.findViewById(R.id.empty_text)).setText(text + ""); } else { child.setVisibility(GONE); } } } /** * * @param tips */ public void showState(String tips) { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 0) { child.setVisibility(VISIBLE); ((TextView) child.findViewById(R.id.load_state_tv)).setText(tips + ""); } else { child.setVisibility(GONE); } } } /** * @param stateId * @param tips */ public void showState(int stateId, String tips) { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i == 0) { child.setVisibility(VISIBLE); ((ImageView) child.findViewById(R.id.load_state_img)).setImageResource(stateId); ((TextView) child.findViewById(R.id.load_state_tv)).setText(tips + ""); } else { child.setVisibility(GONE); } } } /** * 展示內容 */ public void showContent() { for (int i = 0; i < this.getChildCount(); i++) { View child = this.getChildAt(i); if (i > 2 ) { child.setVisibility(VISIBLE); } else { child.setVisibility(GONE); } } } }

測試類LoadingLayoutActivity.java

package com.czhappy.effectdemo.activity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.czhappy.effectdemo.R;
import com.czhappy.effectdemo.loadinglayout.LoadingLayout;

/**
 * Description:
 * User: chenzheng
 * Date: 2017/2/17 0017
 * Time: 18:05
 */
public class LoadingLayoutActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn1, btn2, btn3;
    private LoadingLayout mLoading;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what==1000){
                mLoading.showContent();
            }else if(msg.what==2000){
                mLoading.showState("載入失敗,點選重試!");
            }else if(msg.what==3000){
                mLoading.showEmpty();
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading_layout);

        initView();
    }

    private void initView() {
        mLoading = (LoadingLayout) findViewById(R.id.loading_layout);
        btn1 = (Button) findViewById(R.id.btn1);
        btn2 = (Button) findViewById(R.id.btn2);
        btn3 = (Button) findViewById(R.id.btn3);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);
        mLoading.showContent();
        mLoading.setStateClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLoading.showLoading();
                mLoading.postDelayed(new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        //模擬網路請求
                        mHandler.sendEmptyMessage(2000);
                    }
                },1000);
            }
        });
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn1:
                mLoading.showLoading();
                mLoading.postDelayed(new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        //模擬網路請求
                        mHandler.sendEmptyMessage(1000);
                    }
                },2000);
                break;
            case R.id.btn2:
                mLoading.showLoading();
                mLoading.postDelayed(new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        //模擬網路請求
                        mHandler.sendEmptyMessage(2000);
                    }
                },2000);
                break;
            case R.id.btn3:
                mLoading.showLoading();
                mLoading.postDelayed(new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        //模擬網路請求
                        mHandler.sendEmptyMessage(3000);
                    }
                },2000);
                break;
        }
    }
}

正在載入的佈局檔案loading_layout.xml

至於empty_layout.xml和loadstate_layout.xml這些簡單佈局的程式碼就不貼出來了,根據需要自己定義。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:wheel="http://schemas.android.com/apk/res-auto"
    android:id="@+id/loading_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <com.pnikosis.materialishprogress.ProgressWheel
        android:id="@+id/progress_wheel"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        wheel:matProg_barColor="#5588FF"
        wheel:matProg_progressIndeterminate="true" />

    <TextView
        android:id="@+id/loading_text"
        android:layout_width="wrap_content"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:text="  正在載入..."
        android:textColor="#999999"
        android:textSize="15sp" />
</LinearLayout>

三、注意事項

這裡寫圖片描述