Giter Club home page Giter Club logo

multistatepage's Introduction

MultiStatePage

License

img_2.png

Activity Fragment View ViewPager2
activity.gif fragment.gif view.gif viewpager2.gif
Lottie拓展(自定义State) State刷新 网络请求 sample
lottie.gif net.gif net.gif api.gif

MultiStatePage的功能及特点

  • 无需在布局添加视图代码
  • 可显示自定义状态视图,任意拓展
  • 可用于 Activity、Fragment、或指定的 View
  • 自定义重新请求监听
  • 支持xml直接嵌套且不限制要展示状态内容
  • 可动态更新视图样式
  • 可结合第三方控件使用
  • 支持状态回调监听
  • kotlin开发更易用的API

开始

添加依赖

Step1. Add the JitPack repository to your build file

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Step2. Add the dependency

dependencies {
    implementation 'com.github.Zhao-Yan-Yan:MultiStatePage:2.0.6'
}

1.生成MultiStateContainer

在View上使用

val multiStateContainer = MultiStatePage.bindMultiState(view)
//
val multiStateContainer = view.bindMultiState()

在Activity根View中使用

val multiStateContainer = MultiStatePage.bindMultiState(this)
//
val multiStateContainer = bindMultiState()

在Fragment根View中使用

class MultiStateFragment : Fragment {

    private lateinit var multiStateContainer: MultiStateContainer

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val root = inflater.inflate(R.layout.fragment, container, false)
        multiStateContainer = MultiStatePage.bindMultiState(root)
        //
        multiStateContainer = root.bindMultiState()
        return multiStateContainer
    }
}

xml中引用

<com.zy.multistatepage.MultiStateContainer 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view" 
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</com.zy.multistatepage.MultiStateContainer>

2.切换状态

multiStateContainer.show<CustomState>()
//
multiStateContainer.show(CustomState())

更新state信息

multiStateContainer.show<ErrorState> { errorState ->
    errorState.setErrorMsg("xxx出错了")
}

如何添加重试事件(建议自定义State实现)参考 ErrorState

class ErrorState : MultiState() {

    private lateinit var tvRetry: TextView

    private var retry: OnRetryClickListener? = null

    override fun onCreateView(
        context: Context, inflater: LayoutInflater, container: MultiStateContainer
    ): View {
        return inflater.inflate(R.layout.mult_state_error, container, false)
    }

    override fun onViewCreated(view: View) {
        tvRetry = view.findViewById(R.id.tv_retry)
        tvRetry.setOnClickListener { retry?.retry() }
    }

    fun retry(retry: OnRetryClickListener) {
        this.retry = retry
    }

    fun interface OnRetryClickListener {
        fun retry()
    }
}
multiStateContainer.show<ErrorState> { state ->
    state.retry { do () }
}
//
val state = ErrorState().apply {
    retry { do () }
}
multiStateContainer.show(state)

如何设置默认State

利用kotlin拓展函数可以很轻松的实现

val multiStateActivityRoot = bindMultiState().apply { showEmpty() }

自定义State

继承MultiState

class LottieWaitingState : MultiState() {
    override fun onCreateView(context: Context, inflater: LayoutInflater, container: MultiStateContainer): View {
        // your state view
        return inflater.inflate(R.layout.multi_lottie_waiting, container, false)
    }

    override fun onViewCreated(view: View) {
        //逻辑处理
    }

    override fun onHiddenChanged(hide: Boolean) {
        if (hide) {
            // State 隐藏
        } else {
            // State 显示
        }
    }
}

结合ViewBidng 参考 demo MultiStateBindingWithBindingState

使用内置状态配置

默认内置3种状态(强烈建议您自定义State)

val multiStateContainer = MultiStatePage.bindMultiState(view)
//成功页 
multiStateContainer.show<SuccessState>()
//错误页
multiStateContainer.show<ErrorState>()
//空页面
multiStateContainer.show<EmptyState>()
//加载状态页
multiStateContainer.show<LoadingState>()

更换默认资源

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        val config = MultiStateConfig.Builder()
            .alphaDuration(300)
            .errorIcon(R.mipmap.state_error)
            .emptyIcon(R.mipmap.state_empty)
            .emptyMsg("emptyMsg")
            .loadingMsg("loadingMsg")
            .errorMsg("errorMsg")
            .build()
        MultiStatePage.config(config)
    }
}
Methods Description
alphaDuration alpha动画时长
errorIcon 错误状态默认图标
emptyIcon 空数据状态默认图标
emptyMsg 空数据状态默认提示信息
errorMsg 错误状态默认提示信息
loadingMsg loading状态默认提示信息

小技巧

可以借助kotlin的拓展函数封装常用的状态

fun MultiStateContainer.showSuccess(callBack: (SuccessState) -> Unit = {}) {
    show<SuccessState> { callBack.invoke(it) }
}

fun MultiStateContainer.showError(callBack: (ErrorState) -> Unit = {}) {
    show<ErrorState> { callBack.invoke(it) }
}

fun MultiStateContainer.showEmpty(callBack: (EmptyState) -> Unit = {}) {
    show<EmptyState> { callBack.invoke(it) }
}

fun MultiStateContainer.showLoading(callBack: (LoadingState) -> Unit = {}) {
    show<LoadingState> { callBack.invoke(it) }
}
val multiStateContainer = bindMultiState()
multiStateContainer.showLoading()
multiStateContainer.showSuccess()

下载Demo

点击或者扫描二维码下载

QR code

Thanks

License

Copyright (C) 2020. ZhaoYan

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.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

multistatepage's People

Contributors

wxw-9527 avatar zhao-yan-yan 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

multistatepage's Issues

使用自动刷新框架SmartRefreshLayout 时,bindMultiState(recyclerView),布局显示异常

<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl_refresh"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/cl_toolbar"
app:layout_constraintBottom_toBottomOf="parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/app_dp_9"
        android:background="@color/app_ffd2d0"
        android:overScrollMode="never"/>

</com.scwang.smart.refresh.layout.SmartRefreshLayout>

buildFail

Type com.zy.multistatepage.BuildConfig is defined multiple times: D:\XSHINEIOT\MultiStatePage\app\build\intermediates\project_dex_archive\debug\out\com\zy\multistatepage\BuildConfig.dex, D:\XSHINEIOT\MultiStatePage\app\build\intermediates\external_libs_dex\debug\mergeExtDexDebug\classes.dex

如何在fragment里面的View中使用

如题,我想在一个Fragment中的一个子View中使用MultiStatePage

提示:
2021-10-28 09:26:11.662 25407-25407/cn.caep.stic2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: , PID: 25407
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5361)
at android.view.ViewGroup.addView(ViewGroup.java:5190)
at android.view.ViewGroup.addView(ViewGroup.java:5130)
at androidx.fragment.app.FragmentStateManager.addViewToContainer(FragmentStateManager.java:833)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8668)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

请问支持这个功能吗?

没有loading无隐藏状态

loading的时候应该有两种状态,隐藏布局(加载内容的时候),透明布局遮盖(提交接口的时候),代码中
image会直接替换布局。

可以停止动画吗?

作者大大你好,请问下在StateLoading里面用了自定义的动画,需要在哪里停止这个动画呢,目前showSuccess只是把StateLoading页面隐藏了,但是动画没停止,可以可以加个类似onMultiStateViewCreate的方法来监听页面隐藏了呢
image

compose

compose有没有好的实现方法

重试事件处理 能否新增重试事件的回调

现在统一的都是在bindMultiState里面回调,然而multiStateContainer 我这边有多个状态,每个状态想单独处理【重试事件】

原本

var multiStateContainer =MultiStatePage.bindMultiState(binding!!.root) { v: MultiStateContainer ->
    if(v.id==R.id.login){
    //业务逻辑
    }else if(v.id==R.id.logout){
    //业务逻辑
    }
 }
multiStateContainer.show<LoginState>()
multiStateContainer.show<LogoutState>()

能否改进成

multiStateContainer.show<LogoutState>(){
    //重试按钮点击后回调这里 然后写业务逻辑
}

现在目前的我的解决办法是创建多个multiStateContainer

 MultiStatePage.bindMultiState(binding!!.root) { v: MultiStateContainer ->
               
    }.show<LoginState>()
    
    MultiStatePage.bindMultiState(binding!!.root) { v: MultiStateContainer ->
       
    }.show<LogoutState>()

混淆后程序闪退

需要在proguard-rules.pro中增加配置-keep public class * extends com.zy.multistatepage.MultiState { *; },使继承了MultiState的类不被混淆

点赞!!只为了点赞!!!

是我想要的库,之前找了好多都是要写进布局中的,后来自己找了一个改了改,勉强能用;希望保持更新啊,为你点赞,加油!!

建议:增加状态View扩展性

给MultiStateContainer.kt 类,增加open字段,允许继承该类
使用Java的同学,可以更容易的进行自定义操作

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.