Skip to content

Commit

Permalink
+ 强大的分割线功能
Browse files Browse the repository at this point in the history
+ 分组展开时隐藏分割线
+ ItemBind支持分离绑定逻辑
+ 各种Item接口扩展
  • Loading branch information
liangjingkanji committed Jun 4, 2020
1 parent 48d9b18 commit 2c30a38
Show file tree
Hide file tree
Showing 52 changed files with 1,043 additions and 343 deletions.
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

### 特性

- 使用Databinding构建MVVM
- 完美拥有Kotlin的特性
- 通用适配器
- 方便实现常见需求
- 代码量最少, 逻辑更清晰
- 全网最少的代码
- Kotlin的特性
- 通用适配器, 无需继承
- 快速实现常见需求
- 刷新还是添加数据都无闪屏


Expand All @@ -28,6 +27,13 @@

- 过滤重复点击

- 分组

- 展开折叠
- 顶部附着

- 支持所有的`LayoutManager`的分割线/均布间隔

- 切换模式

- 选择模式
Expand All @@ -39,7 +45,7 @@

- 侧滑删除

- 下拉刷新 | 上拉加载 (PageRefreshLayout|SmartRefreshLayout)
- 下拉刷新 | 上拉加载 (PageRefreshLayout)

- 多状态缺省页 (PageRefreshLayout)

Expand All @@ -57,9 +63,6 @@
未来将支持:

- 无限滚动
- 分组
- 展开折叠
- 顶部附着

## 安装

Expand All @@ -79,7 +82,7 @@ allprojects {
module 的 build.gradle

```groovy
implementation 'com.github.liangjingkanji:BRV:1.2.11'
implementation 'com.github.liangjingkanji:BRV:1.2.13'
```


Expand Down
56 changes: 35 additions & 21 deletions brv/src/main/java/com/drake/brv/BindingAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.drake.brv.animation.*
import com.drake.brv.annotaion.AnimationType
import com.drake.brv.item.ItemBind
import com.drake.brv.item.ItemExpand
import com.drake.brv.item.ItemHover
import com.drake.brv.item.ItemPosition
Expand All @@ -45,9 +46,6 @@ import com.drake.brv.listener.throttleClick
* 强大的选择状态 [setChecked] (切换模式/多选/单选/全选/取消全选/反选/选中数据集/选中数量/单选和多选模式切换)
* 遵守高内聚低耦合原则, 支持功能配合使用, 代码简洁函数分组
*
* TODO
* [] 无限划动
* [] 拖动多选
*/

@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate")
Expand Down Expand Up @@ -103,7 +101,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder {

val viewDataBinding = DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(parent.context), viewType, parent, false)
?: return BindingViewHolder(parent.getView(viewType))
?: return BindingViewHolder(parent.getView(viewType))

return BindingViewHolder(viewDataBinding)
}
Expand All @@ -130,7 +128,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
val model = getModel<Any>(position)
val modelClass: Class<*> = model.javaClass
return (typePool[modelClass]?.invoke(model, position)
?: throw NoSuchPropertyException("Please add item model type : ${model.javaClass.simpleName}"))
?: throw NoSuchPropertyException("Please add item model type : ${model.javaClass.simpleName}"))
}

override fun getItemCount() = headerCount + modelCount + footerCount
Expand Down Expand Up @@ -268,7 +266,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
/**
* 设置当前库自带的条目的动画样式
*/
fun setAnimation(@AnimationType animationType: Int) {
fun setAnimation(animationType: AnimationType) {
this.animationEnabled = true
when (animationType) {
AnimationType.ALPHA -> this.itemAnimation = AlphaItemAnimation()
Expand Down Expand Up @@ -336,7 +334,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()


fun isHeader(@IntRange(from = 0) position: Int): Boolean =
(headerCount > 0 && position < headerCount)
(headerCount > 0 && position < headerCount)

// </editor-fold>

Expand Down Expand Up @@ -426,7 +424,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()


fun isFooter(@IntRange(from = 0) position: Int): Boolean =
(footerCount > 0 && position >= headerCount + modelCount && position < itemCount)
(footerCount > 0 && position >= headerCount + modelCount && position < itemCount)

// </editor-fold>

Expand Down Expand Up @@ -484,7 +482,8 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
return result
}

fun isModel(@IntRange(from = 0) position: Int): Boolean = !(isHeader(position) || isFooter(position))
fun isModel(@IntRange(from = 0) position: Int): Boolean =
!(isHeader(position) || isFooter(position))

/**
* 根据索引返回数据模型, 如果不存在该模型则返回Null
Expand Down Expand Up @@ -719,9 +718,15 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()

//<editor-fold desc="分组">

private var onExpand: (BindingViewHolder.(Boolean) -> Unit)? = null

// 分组展开和折叠是否启用动画
var expandAnimationEnabled: Boolean = true

fun onExpand(block: BindingViewHolder.(Boolean) -> Unit) {
this.onExpand = block
}

/**
* 展开
* @param position 指定position的条目折叠
Expand Down Expand Up @@ -765,7 +770,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
lateinit var data: Any

val adapter: BindingAdapter = this@BindingAdapter
val modelPosition get() = adapterPosition - headerCount
val modelPosition get() = layoutPosition - headerCount

constructor(itemView: View) : super(itemView)

Expand Down Expand Up @@ -797,15 +802,20 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
internal fun bind(model: Any) {
this.data = model

if (model is ItemPosition) {
model.itemPosition = layoutPosition
}

if (model is ItemBind) {
model.onBind(this)
return
}

onBind?.apply {
val isReturn = onBind!!.invoke(this@BindingViewHolder)
if (isReturn) return
}

if (model is ItemPosition) {
model.itemPosition = layoutPosition
}

viewDataBinding?.setVariable(modelId, model)
viewDataBinding?.executePendingBindings()
}
Expand Down Expand Up @@ -837,19 +847,21 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
fun expand(scrollTop: Boolean = true, @IntRange(from = -1) depth: Int = 0): Int {
val itemExpand = getModelOrNull<ItemExpand>()

onExpand?.invoke(this, true)

return if (itemExpand != null && !itemExpand.itemExpand) {
val sublist = itemExpand.itemSublist
itemExpand.itemExpand = true

if (sublist.isNullOrEmpty()) {
notifyItemChanged(adapterPosition)
notifyItemChanged(layoutPosition)
0
} else {
val sublistFlat = flat(sublist, true, depth) ?: return 0
this@BindingAdapter.data?.addAll(adapterPosition + 1, sublistFlat)
this@BindingAdapter.data?.addAll(layoutPosition + 1, sublistFlat)
if (expandAnimationEnabled) {
notifyItemChanged(adapterPosition)
notifyItemRangeInserted(adapterPosition + 1, sublistFlat.size)
notifyItemChanged(layoutPosition)
notifyItemRangeInserted(layoutPosition + 1, sublistFlat.size)
} else {
notifyDataSetChanged()
}
Expand All @@ -871,19 +883,21 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
fun collapse(@IntRange(from = -1) depth: Int = 0): Int {
val itemExpand = getModelOrNull<ItemExpand>()

onExpand?.invoke(this, false)

return if (itemExpand != null && itemExpand.itemExpand) {
val sublist = itemExpand.itemSublist
itemExpand.itemExpand = false

if (sublist.isNullOrEmpty()) {
notifyItemChanged(adapterPosition, itemExpand)
notifyItemChanged(layoutPosition, itemExpand)
0
} else {
val sublistFlat = flat(sublist, false, depth) ?: return 0
this@BindingAdapter.data?.removeAll(sublistFlat)
if (expandAnimationEnabled) {
notifyItemChanged(adapterPosition, itemExpand)
notifyItemRangeRemoved(adapterPosition + 1, sublistFlat.size)
notifyItemChanged(layoutPosition, itemExpand)
notifyItemRangeRemoved(layoutPosition + 1, sublistFlat.size)
} else {
notifyDataSetChanged()
}
Expand Down
Loading

0 comments on commit 2c30a38

Please sign in to comment.