Giter Site home page Giter Site logo

liangjingkanji / brv Goto Github PK

View Code? Open in Web Editor NEW
2.4K 31.0 311.0 19.29 MB

[使用文档] Android 快速构建 RecyclerView, 比 BRVAH 更简单强大

Home Page: http://liangjingkanji.github.io/BRV/

License: MIT License

Java 35.25% Kotlin 64.75%
recyclerview

brv's Introduction

中文 | English

1600

可能是最强大的RecyclerView框架

使用文档 | 无法访问? | 贡献代码 | 下载体验


BRV为快速构建RV列表工具, 以开源分享来完善, 将一直保持社区维护

Welcome to international translation of this project's documents/notes, thank you for your support!


欢迎贡献代码/问题


  • 开发效率No.1
  • 永远保持社区维护
  • 低代码/高扩展性
  • 优秀的源码/注释/文档/示例

功能

  • 快速创建多类型列表
  • 一对一/一对多创建多类型
  • 添加头布局和脚布局
  • 点击(防抖动)/长按事件
  • 分组(展开折叠/递归层次/展开置顶/拖拽/侧滑/多类型/单一展开模式)
  • 悬停/粘性头部
  • 快速创建分隔线/间隔
  • 切换模式(例如切换编辑模式)
  • 选择模式(多选/单选/全选/取消全选/反选)
  • 拖拽排序
  • 侧滑删除
  • 下拉刷新(Refresh) | 上拉加载(LoadMore) | 下拉加载(UpFetch), 由SmartRefreshLayout实现
  • 预加载(Preload)
  • 对比数据更新(Diffs)
  • 自动分页加载数据
  • 列表动画/骨骼图动画
  • 列表缺省页, 由StateLayout实现
  • 支持DataBinding
  • 支持ViewBinding
  • 可添加FlexboxLayoutManager实现伸缩列表自动换行
  • 可添加Net(强大的协程网络请求)实现自动化网络请求

安装

Project 的 settings.gradle 添加仓库

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

Module 的 build.gradle 添加依赖框架

dependencies {
    implementation 'com.github.liangjingkanji:BRV:1.5.8'
}

License

MIT License

Copyright (c) 2023 劉強東

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

brv's People

Contributors

bobskycn avatar chawloo avatar dingxiansen1 avatar dlisagod avatar hubrains avatar liangjingkanji avatar liyuxx avatar lukelmouse-github avatar lvshqc avatar lxzbug avatar lzkdreamer avatar mcxinyu avatar roc-egg avatar shenbengit avatar the6nnoo avatar txca avatar uni-cstar 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brv's Issues

请教

请问下,项目中 能否只启用viewbinding,不启用databinding?

分组模式下,能否支持拖拽?例如,父A层级 下的子AA 拖拽到父 B 下;或者 整个父A 拖拽到 父B下;又或者。父A 整个托拽到父B下的子BB下面

datadingding自动刷新item

大佬问下使用databinding修改完item子控件的数据之后,只刷新item的子控件要怎么实现?

悬停问题

上拉加载更多的时候,悬停的item也会一起向上移动了

嵌套分组,关闭和展开存在Bug(或是我食用方法不对?)

分组,在关闭展开后,会导致item自己成倍增加。

brv


示例代码:

Activity And Bean

data class TestBean(val name: String, val subset: List<TestBean>) : ItemExpand {
    override var itemGroupPosition: Int = 0
    override var itemExpand: Boolean = false
    override var itemSublist: List<Any?>? = subset

    //color 只是为了展示区分
    val color: Int
        get() = when {
            name.contains("A") -> {
                Color.GRAY
            }
            name.contains("B") -> {
                Color.GREEN
            }
            name.contains("C") -> {
                Color.BLUE
            }
            name.contains("D") -> {
                Color.RED
            }
            else -> {
                throw IllegalArgumentException()
            }
        }
}

class TestGroupActivity : AppCompatActivity() {

    private lateinit var adapter: BindingAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_group)

        adapter = findViewById<RecyclerView>(R.id.rv_test).linear().setup {
            addType<TestBean>(R.layout.item_test)

            onClick(R.id.v_container) {
                expandOrCollapse()
            }
        }

        initData()
    }

    private fun initData() {
        adapter.models = mutableListOf<TestBean>().apply {
            repeat(1) { a ->
                add(TestBean("A_$a", mutableListOf<TestBean>().apply {

                    repeat(5) { b ->
                        add(TestBean("B_$b", mutableListOf<TestBean>().apply {

                            repeat(5) { c ->
                                add(TestBean("C_$c", mutableListOf<TestBean>().apply {

                                    repeat(5) { d ->
                                        add(TestBean("D_$d", emptyList()))
                                    }
                                }))
                            }
                        }))
                    }
                }))
            }
        }
    }
}

activity_test_group.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

</LinearLayout>

item_test.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="x"
            type="test.TestBean" />
    </data>

    <LinearLayout
        android:id="@+id/v_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textColor="@{x.color}"
            android:text="@{x.name}" />
    </LinearLayout>
</layout>

不愧是Android最强大的RecyclerView框架

确实是我用过最强大的RecyclerView框架,以后我使用到RecyclerView必将使用到这个框架,希望作者可以维护下去,我也会多写一些文章宣传的(虽然我是菜鸡😂)

已经用上了,确实十分强大

仓库介绍中写着,无论是不是要databinding,但文档中并没有这么强调,所以想询问一下,下面的代码到底是必要的还是非必要的

apply plugin: "kotlin-kapt" // kapt插件用于生成dataBinding

android {
    /.../
    buildFeatures.dataBinding = true
}

使用PageRefreshLayout会编译不通过,报找不到NestedScrollingParent的类文件

` <com.drake.brv.PageRefreshLayout
android:id="@+id/page"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_list_title"
app:stateEnabled="true">

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

            </com.drake.brv.PageRefreshLayout>`

错误: cannot generate view binders com.sun.tools.javac.code.Symbol$CompletionFailure: 找不到android.support.v4.view.NestedScrollingParent的类文件

试过1.3.33和1.3.35都是

ClassCastException: kotlin.collections.EmptyList cannot be cast to kotlin.collections.MutableList

手机型号:小米6
Android:9
操作:头|脚布局-----> 添加头部

2020-05-23 11:08:47.112 27889-27889/com.drake.brv.sample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.drake.brv.sample, PID: 27889
java.lang.ClassCastException: kotlin.collections.EmptyList cannot be cast to kotlin.collections.MutableList
at com.drake.brv.BindingAdapter.addHeader(BindingAdapter.kt:300)
at com.drake.brv.BindingAdapter.addHeader$default(BindingAdapter.kt:297)
at com.drake.brv.sample.ui.fragment.HeaderFooterFragment$initToolbar$1.onMenuItemClick(HeaderFooterFragment.kt:74)
at androidx.appcompat.widget.Toolbar$1.onMenuItemClick(Toolbar.java:207)
at androidx.appcompat.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:781)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
at androidx.appcompat.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
at android.widget.AdapterView.performItemClick(AdapterView.java:318)
at android.widget.AbsListView.performItemClick(AbsListView.java:1198)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3178)
at android.widget.AbsListView$3.run(AbsListView.java:4132)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:6878)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)

BRV数据更新问题

你好,我在viewpager2+fragment中使用BRV,recyclerView.linear().setup {
addType(R.layout.item_task)
}, fragment中使用相同布局、相同model、不同fragment请求数据不同,但是加载出来都是第一个fragment请求的数据。这是什么原因导致的呢。

刷新闪烁问题

当我的recyclerView的Header里还有一个横向的recyclerView里时,两个recyclerview的数据还是通过两个接口获取时,这时候刷新两个列表都会闪一下。请问下作者是如何处理刷新闪烁问题的?谢谢。

万能分割线在layoutManager为LinearLayoutManager 如何设置左右边距

如题,在设置LinearLayoutManager 后,添加了分割线代码如下

mDataBind.listRecyclerView.vertical().divider {
            orientation = DividerOrientation.VERTICAL
            startVisible = true
            endVisible = true
            setDivider(10,true)
            setMargin(8,8)
        }.adapter = testAdapter

想通过setMargin方法设置左右两边的边距,但是没有效果,想问一下,目前万能分割线是否支持这种需求呢?

网格分割线有个bug

在网格列表中,使用网格分割线,均布间隔,但是在累加数据时会出现分割线间隔不一致的bug 如图:
Screenshot_20210610_143042

页面回退时候, binding.page.onRefresh() 会被执行两次

非常好的rv库, 使用中碰到一个问题.

当列表也点击到详情页, 再从详情页退回到列表也时候, binding.page.onRefresh() {} 会被执行两次, 回退时候没有手动执行刷新代码

有时候用 binding.page.refresh() 刷新也会执行两次, 不知道那里出问题了

PageRefreshLayout有个bug

PageRefreshLayout的showLoading函数中,stateLayout?.showLoading(tag, refresh)有误,应该是stateLayout?.showLoading(tag, refresh=refresh)

不使用DataBinding会直接崩溃

version:1.3.13

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/databinding/DataBinderMapperImpl;
at androidx.databinding.DataBindingUtil.(DataBindingUtil.java:32)
at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)
at com.drake.brv.BindingAdapter.onCreateViewHolder(BindingAdapter.kt:127)
at com.drake.brv.BindingAdapter.onCreateViewHolder(BindingAdapter.kt:67)
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7078)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6235)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)

分组列表模式下,对于嵌套分组对象是否可以增加一个字段记录当前层级(深度)

如题

data class ItemData(
    val name: String,
    val subset: List<ItemData>,
) : ItemExpand {
    // 同级别分组的索引位置
    override var itemGroupPosition: Int = 0

    // 当前条目是否展开
    override var itemExpand: Boolean = false

    // 该变量存储子列表
    override var itemSublist: List<Any?>? = emptyList()
        get() = subset

    // 新增一个能记录当前层级的字段,用于UI嵌套对象UI判断偏移位置
    var level ? depth ...
}

尝试使用1.3.31版本时,无法正确加载项目

Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.scwang.smart:refresh-layout-kernel:2.0.3.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not resolve com.scwang.smart:refresh-footer-classics:2.0.3.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.scwang.smart:refresh-footer-classics:2.0.3.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not resolve com.scwang.smart:refresh-layout-kernel:2.0.3.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not resolve com.scwang.smart:refresh-layout-kernel:2.0.3.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not resolve com.scwang.smart:refresh-header-material:2.0.1.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.scwang.smart:refresh-header-material:2.0.1.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not resolve com.scwang.smart:refresh-header-material:2.0.1.
Show Details
Affected Modules: app

Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not resolve com.scwang.smart:refresh-footer-classics:2.0.3.
Show Details
Affected Modules: app

增加数据新增时,滑动到新增数据位置的功能

现在的实现方法是这样子的

recyclerView.setup{
    registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
        override fun onChanged() {
           recyclerView.smoothScrollToPosition(this@setup.modelCount)
           // 在收到onChanged后 直接滑动到最后一个
        }
    })
}

测试了registerAdapterDataObserver中的其他回调 都收不到任何通知

个人的一点思路(暂时没有多少时间完善代码,如采纳此需求可有空后提交pr)

/** 数据模型集合 */
var models: List<Any?>? = null
    set(value) {
        // TODO 在此处做一下数据的 Diff 判断,按需调用notify
         ......
    }

增加一个默认的AdapterDataObserver,通过开关管理在添加新数据后的动作

按readme上配置,但是有依赖不对

只用了implementation 'com.github.liangjingkanji:BRV:1.3.26'但是报错了

Failed to resolve: com.scwang.smart:refresh-footer-classics:2.0.1
Show in Project Structure dialog
Affected Modules: app

Failed to resolve: com.scwang.smart:refresh-layout-kernel:2.0.1
Show in Project Structure dialog
Affected Modules: app

Failed to resolve: com.scwang.smart:refresh-header-material:2.0.1
Show in Project Structure dialog
Affected Modules: app

但是sample是可以运行的,这3个也加到依赖去还是会报错

有个关于选中数据删除的bug

就是移除选中的item之后再notifyDataSetChange更新,数据和rv是有变化了,但是checkCount是不会更新变化的,还是之前的。

private val adapter get() = vb.rvUser.bindingAdapter
private val checkCount get() = adapter.checkedCount
private val checkList get() = adapter.getCheckedModels()

fun delete(){
adapter.mutable.removeAll(checkList)
adapter.notifyDataSetChanged()
//这里之后获取的checkedCount还是之前的数据
}

我有试过把删除的position setCheck为false,但是我看了setCheck里面是checkPosition调用remove的,所以我循环iterator移除也依然会ConcurrentModificationException

adapter.notifyItemRemove也是一样情况

这种情况还是得自己管理一个选中的记录

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.