自定义页面加载LoadingLayout

做项目当中总是遇到页面数据加载的情况,自定义了几个加载情况的xml布局,例如加载失败,加载数据为空,加载成功,正在加载等,但是发现每次都需要根据加载情况去处理显示哪种xml,很麻烦,也很容易出错,所以我就想以自定义组合控件的方式来处理,达到复用的目的,代码可优化的地方有很多,大家可以根据自己的需求做修改。

首先自定义属性了:

    <!--loadinglayout-->
    <declare-styleable name="LoadingLayout">
        <attr name="loadingLayoutId" format="reference"/>
        <attr name="failureLayoutId" format="reference"/>
        <attr name="emptyLayoutId" format="reference"/>
        <attr name="contentId" format="reference"/>
    </declare-styleable>

代码很简单,自己看看

public class LoadingLayout extends FrameLayout {

    private View loadingView, failureView, emptyView, contentView;

    private RetryListener retryListener;

    public LoadingLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingLayout(Context context) {
        this(context, null);
    }

    public LoadingLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadingLayout, defStyleAttr, 0);

        int loadingId = typedArray.getResourceId(R.styleable.LoadingLayout_loadingLayoutId, 0);

        int failureId = typedArray.getResourceId(R.styleable.LoadingLayout_failureLayoutId, 0);

        int emptyId = typedArray.getResourceId(R.styleable.LoadingLayout_emptyLayoutId, 0);

        int contentId = typedArray.getResourceId(R.styleable.LoadingLayout_contentId, 0);

        typedArray.recycle();

        initView(context, loadingId, failureId, emptyId, contentId);

    }

    //初始化三个状态View
    private void initView(Context context, int loadingId, int failureId, int emptyId, int contentId) {

        createChildView(context, loadingId);
        createChildView(context, failureId);
        createChildView(context, emptyId);
        createChildView(context, contentId);
    }

    //创建子视图
    private void createChildView(Context context, int Id) {

        if (Id!=0) {

            View.inflate(context,Id, this);
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //获取显示内容区域
        if (getChildCount() > 3) {
            loadingView = getChildAt(0);
            failureView = getChildAt(1);
            emptyView = getChildAt(2);
            contentView = getChildAt(3);
            contentView.setVisibility(GONE);
            if (loadingView != null) {

                loadingView.setVisibility(GONE);
            }

            if (failureView != null) {

                failureView.setVisibility(GONE);
                View rButton = (failureView.findViewById(R.id.tv_retry) == null) ? failureView : failureView.findViewById(R.id.tv_retry);
                rButton.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        if (retryListener != null) {

                            retryListener.retryClick();

                        }
                    }
                });
            }

            if (emptyView != null) {

                emptyView.setVisibility(GONE);
            }

        }

    }

    //设置重试监听
    public void setRetryListener(RetryListener retryListener) {
        this.retryListener = retryListener;
    }

    //显示加载view
    public void showLoading() {

        show(1);

    }

    //显示失败view
    public void showFailure() {

        show(2);

    }

    //显示空view
    public void showEmpty() {

        show(3);

    }

    //显示空view
    public void showContent() {

        show(4);
    }

    //根据id展示布局
    private void show(int id) {

        if (loadingView != null) {

            loadingView.setVisibility(id == 1 ? VISIBLE : GONE);
        }

        if (failureView != null) {

            failureView.setVisibility(id == 2 ? VISIBLE : GONE);

        }

        if (emptyView != null) {

            emptyView.setVisibility(id == 3 ? VISIBLE : GONE);
        }

        if (contentView != null) {

            contentView.setVisibility(id == 4 ? VISIBLE : GONE);
        }
    }

    public interface RetryListener {

        void retryClick();

    }

}

然后就是如何使用了

<?xml version="1.0" encoding="utf-8"?>
<com.yjjy.app.view.LoadingLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/loadingLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:loadingLayoutId="@layout/progressdialoag"
    app:failureLayoutId="@layout/loading_failure"
    <!--可以在这里引用设置contentlayout-->
    >
        <!--也可以在这里引用设置contentlayout-->
</com.yjjy.app.view.LoadingLayout>

然后在使用的地方调用下面几个方法即可:

    //显示加载view
    public void showLoading() {

        show(1);

    }

    //显示失败view
    public void showFailure() {

        show(2);

    }

    //显示空view
    public void showEmpty() {

        show(3);

    }

    //显示空view
    public void showContent() {

        show(4);
    }
时间: 2024-10-14 13:16:47

自定义页面加载LoadingLayout的相关文章

Html5添加小巧的自定义页面加载loading指示器插件教程

一.使用方法 <script src="js/jquery-2.1.4.min.js"></script> <script src="dist/jquery.showLoading.min.js"></script> 二.CSS .loading-indicator { height: 80px; width: 80px; background: url('loading.gif') no-repeat center

定义页面加载和导航时要执行的函数/自定义事件

/** * Copyright 2017 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www

java selenium (十三) 智能等待页面加载完成

我们经常会碰到用selenium操作页面上某个元素的时候, 需要等待页面加载完成后, 才能操作.  否则页面上的元素不存在,会抛出异常. 或者碰到AJAX异步加载,我们需要等待元素加载完成后, 才能操作 selenium 中提供了非常简单,智能的方法,来判断元素是否存在. 阅读目录 实例要求 实例:set_timeout.html 下面的html 代码,  点击click 按钮5秒后, 页面上会出现一个红色的div快, 我们需要写一段自动化脚本智能的去判断这个div是否存在, 然后把这个div

Java Selenium (十二) 操作弹出窗口 &amp; 智能等待页面加载完成 &amp; 处理 Iframe 中的元素

一.操作弹出窗口   原理 在代码里, 通过 Set<String> allWindowsId = driver.getWindowHandles(); 来获取到所有弹出浏览器的句柄, 然后遍历, 使用swithcto.window(newwindow_handle)方法. 就可以定位到新的窗口. 测试页面的HTML <html> <head> <title>常见web ui元素操作, 及API使用</title> <script type

fakeLoader页面加载前loading演示8种效果

提高用户体验的插件fakeLoader页面加载前loading演示8种效果 在线预览 下载地址 示例代码 <div id="main"> <div class="demo"> <a href="/api/jq/5733e326a88fd/index.html" class="cur">Spinner1 </a> <a href="/api/jq/5733e326a

js页面加载进度条(这个就比较正式了,改改时间就完事儿)

不废话,直接上代码 思路不难,就是一个animate方法配合随机数 duration内个三秒钟,是自定义的,可以改成页面加载时间,这样就完美了 <!doctype html> <html> <head> <meta charset="utf-8"> <title>无标题文档</title> <script src="js/jquery-1.8.3.min.js"></scrip

关于selenium的智能等待页面加载的问题

我们经常会碰到用selenium操作页面上某个元素的时候,需要等待页面加载完成后,才能操作, 否则页面上的元素不存在,会抛出异常. 或者碰到AJAX异步加载,我们需要等待元素加载完成后,才能操作. 首先来讲,我们最不推荐的就是使用  Thread.sleep( ) ;  这个也叫做线程休眠. 这种写法通常是固定了一个时间,然而我们不知道页面具体的等待情况,有快有慢,虽然很百搭,但是并不适用于框架中. selenium 中提供了非常简单,智能的方法,来判断元素是否存在.我来简单的举例说明几种(在我

JSFF或JSF页面加载时触发JavaScript之方法

现象一 最近在项目中遇到这么一个问题,有些页面元素是在页面加载时通过JavaScript动态渲染而成.当生成这些元素的JavaScript脚本被放置于JSPX文件中时,界面渲染没有问题.但是当我们把生成这些页面元素的JS脚本放到JSFF时就会发现,JS脚本只在我们进入TaskFlow的第一个View被执行了,进入后续View时,后续View的JS代码加载和执行. 分析 通过分析,发现当进入TaskFlow的第一个View时,第一个View中通过<af:resource/>标签引入的JS代码能成

JS实现页面加载完毕之前loading提示效果

1.获取浏览器页面可见高度和宽度 var _PageHeight = document.documentElement.clientHeight, _PageWidth = document.documentElement.clientWidth; 2.计算loading框距离顶部和左部的距离(loading框的宽度为215px,高度为61px) var _LoadingTop = _PageHeight > 61 ? (_PageHeight - 61) / 2 : 0, _LoadingLe