GithubHelp home page GithubHelp logo

composestatelayout's Introduction

前言

在页面中常常需要展示网络请求状态,以带来更好的用户体验,具体来说通常有加载中加载失败加载为空加载成功等状态.

XML中我们通常用一个ViewGroup封装各种状态来实现,那么使用Compose该如何实现这种效果呢?

本文主要介绍Compose如何封装一个简单易用的StateLayout,有兴趣的同学可以点个Star:Compose版StateLayout

效果图

首先看下最终的效果图

特性

  1. 支持配置全局默认布局,如默认加载中,默认成功失败等
  2. 支持自定义默认样式文案,图片等细节
  3. 支持完全自定义样式,如自定义加载中样式
  4. 支持自定义处理点击重试事件
  5. 完全使用数据驱动,使用简单,接入方便

使用

接入

第 1 步:在工程的build.gradle中添加:

allprojects {
	repositories {
		...
		mavenCentral()
	}
}

第2步:在应用的build.gradle中添加:

dependencies {
        implementation 'io.github.shenzhen2017:compose-statelayout:1.0.0'
}

简单使用

定义全局样式

在框架中没有指定任何默认样式,因此你需要自定义自己的默认加载中,加载失败等页面样式

同时需要自定义传给自定义样式的数据结构类型,方便数据驱动

data class StateData(
    val tipTex: String? = null,
    val tipImg: Int? = null,
    val btnText: String? = null
)

@Composable
fun DefaultStateLayout(
    modifier: Modifier = Modifier,
    pageStateData: PageStateData,
    onRetry: OnRetry = { },
    loading: @Composable (StateLayoutData) -> Unit = { DefaultLoadingLayout(it) },
    empty: @Composable (StateLayoutData) -> Unit = { DefaultEmptyLayout(it) },
    error: @Composable (StateLayoutData) -> Unit = { DefaultErrorLayout(it) },
    content: @Composable () -> Unit = { }
) {
    ComposeStateLayout(
        modifier = modifier,
        pageStateData = pageStateData,
        onRetry = onRetry,
        loading = { loading(it) },
        empty = { empty(it) },
        error = { error(it) },
        content = content
    )
}

如上所示,初始化时我们主要需要做以下事

  1. 自定义默认加载中,加载失败,加载为空等样式
  2. 自定义StateData,即传给默认样式的数据结构,比如文案,图片等,这样后续需要修改的时候只需修改StateData即可

直接使用

如果我们直接使用默认样式,直接如下使用即可

@Composable
fun StateDemo() {
    var pageStateData by remember {
        mutableStateOf(PageState.CONTENT.bindData())
    }
    DefaultStateLayout(
        modifier = Modifier.fillMaxSize(),
        pageStateData = pageStateData,
        onRetry = {
            pageStateData = PageState.LOADING.bindData()
        }
    ) {
        //Content
    }
}

如上所示,可以直接使用,如果需要修改状态,修改pageStateData即可

自定义文案

如果我们需要自定义文案或者图片等细节,可简单直接修改StateData即可

fun StateDemo() {
    var pageStateData by remember {
        mutableStateOf(PageState.CONTENT.bindData())
    }
    //....
    pageStateData = PageState.LOADING.bindData(StateData(tipTex = "自定义加载中文案"))
}

自定义布局

有时页面的加载中样式与全局的并不一样,这就需要自定义布局样式了

@Composable
fun StateDemo() {
    var pageStateData by remember {
        mutableStateOf(PageState.CONTENT.bindData())
    }
    DefaultStateLayout(
        modifier = Modifier.fillMaxSize(),
        pageStateData = pageStateData,
        loading = { CustomLoadingLayout(it) },
        onRetry = {
            pageStateData = PageState.LOADING.bindData()
        }
    ) {
        //Content
    }
}

主要原理

其实Compose要实现不同的状态非常简单,传入不同的数据即可,如下所示:

    Box(modifier = modifier) {
        when (pageStateData.status) {
            PageState.LOADING -> loading()
            PageState.EMPTY -> empty()
            PageState.ERROR -> error()
            PageState.CONTENT -> content()
        }
    }

其实代码非常简单,但是这段代码是个通用逻辑,如果每个页面都要写这一段代码可能也挺烦的

所以这段代码其实是模板代码,我们想到Scaffold脚手架,提供了组合各个组件的API,包括标题栏、底部栏、SnackBar(类似吐司功能)、浮动按钮、抽屉组件、剩余内容布局等,让我们可以快速定义一个基本的页面结构。

仿照Scaffold,我们也可以定义一个模板组件,用户可以传入自定义的looading,empty,error,content等组件,再将它们组合起来,这样就形成了ComposeStateLayout

data class PageStateData(val status: PageState, val tag: Any? = null)

data class StateLayoutData(val pageStateData: PageStateData, val retry: OnRetry = {})

typealias OnRetry = (PageStateData) -> Unit

@Composable
fun ComposeStateLayout(
    modifier: Modifier = Modifier,
    pageStateData: PageStateData,
    onRetry: OnRetry = { },
    loading: @Composable (StateLayoutData) -> Unit = {},
    empty: @Composable (StateLayoutData) -> Unit = {},
    error: @Composable (StateLayoutData) -> Unit = {},
    content: @Composable () -> Unit = { }
) {
    val stateLayoutData = StateLayoutData(pageStateData, onRetry)
    Box(modifier = modifier) {
        when (pageStateData.status) {
            PageState.LOADING -> loading(stateLayoutData)
            PageState.EMPTY -> empty(stateLayoutData)
            PageState.ERROR -> error(stateLayoutData)
            PageState.CONTENT -> content()
        }
    }
}

如上所示,代码很简单,主要需要注意以下几点:

  1. PageStateDatatag即传递给自定义loading等页面的信息,为Any类型,没有任何限制,用户可灵活处理
  2. 自定义loading等页面也传入了OnRetry,因此我们也可以处理自定义点击事件

总结

本文主要实现了一个Compose版的StateLayout,它具有以下特性

  1. 支持配置全局默认布局,如默认加载中,默认成功失败等
  2. 支持自定义默认样式文案,图片等细节
  3. 支持完全自定义样式,如自定义加载中样式
  4. 支持自定义处理点击重试事件
  5. 完全使用数据驱动,使用简单,接入方便

项目地址

简单易用的Compose版StateLayout

开源不易,如果项目对你有所帮助,欢迎点赞,Star,收藏~

composestatelayout's People

Contributors

ricardojiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.