Skip to content

Commit

Permalink
+ 可不使用DataBinding
Browse files Browse the repository at this point in the history
| 修复缺省页关闭后无法上拉加载问题
  • Loading branch information
liangjingkanji committed Jun 29, 2020
1 parent 1c512cd commit 1b3dd2a
Show file tree
Hide file tree
Showing 19 changed files with 251 additions and 125 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

配合异步网络任务库[Net](https://github.com/liangjingkanji/Net)预计可为项目减少70%代码



任何框架问题加群回复: [752854893](https://jq.qq.com/?_wv=1027&k=vWsXSNBJ)


Expand All @@ -15,7 +17,7 @@
- 快速实现常见需求
- 刷新还是添加数据都无闪屏
- Demo示例代码不过百行
- 可配合DataBinding实现MVVM架构
- 可配合DataBinding快速实现MVVM架构(也可以不使用DataBinding)

### 需求

Expand Down Expand Up @@ -89,7 +91,7 @@ allprojects {
module 的 build.gradle

```groovy
implementation 'com.github.liangjingkanji:BRV:1.3.5'
implementation 'com.github.liangjingkanji:BRV:1.3.6'
```


Expand All @@ -116,7 +118,7 @@ class MyApplication : Application() {
override fun onCreate() {
super.onCreate()

BindingAdapter.modelId = BR.m // 推荐在Application中进行初始化或使用之前即可
BRV.modelId = BR.m // 推荐在Application中进行初始化或使用之前即可
}
}
```
Expand Down
82 changes: 33 additions & 49 deletions brv/src/main/java/com/drake/brv/BindingAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package com.drake.brv


import android.content.Context
import android.util.NoSuchPropertyException
import android.util.SparseBooleanArray
import android.view.LayoutInflater
Expand All @@ -32,6 +33,7 @@ import com.drake.brv.listener.DefaultItemTouchCallback
import com.drake.brv.listener.OnBindViewHolderListener
import com.drake.brv.listener.OnHoverAttachListener
import com.drake.brv.listener.throttleClick
import com.drake.brv.utils.BRV

/**
* < Android上最强大的RecyclerView框架 >
Expand Down Expand Up @@ -68,12 +70,12 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
则应在Application中的[onCreate]函数内设置:
BindingAdapter.modelId = BR.m
*/
var modelId: Int = -1
var modelId: Int = BRV.modelId
}


// <editor-fold desc="生命周期">
private var onBind: (BindingViewHolder.() -> Boolean)? = null
private var onBind: (BindingViewHolder.() -> Unit)? = null
private var onPayload: (BindingViewHolder.(Any) -> Unit)? = null
private var onClick: (BindingViewHolder.(viewId: Int) -> Unit)? = null
private var onLongClick: (BindingViewHolder.(viewId: Int) -> Unit)? = null
Expand All @@ -86,7 +88,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
* [onBindViewHolder]回调
* @return true表示不使用DataBinding, false则使用(默认)
*/
fun onBind(block: BindingViewHolder.() -> Boolean) {
fun onBind(block: BindingViewHolder.() -> Unit) {
onBind = block
}

Expand All @@ -102,15 +104,11 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()

// <editor-fold desc="覆写函数">

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder {
private var context: Context? = null

val viewDataBinding = DataBindingUtil.inflate<ViewDataBinding>(
LayoutInflater.from(parent.context),
viewType,
parent,
false
)
?: return BindingViewHolder(parent.getView(viewType))
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(viewDataBinding)
}
Expand All @@ -123,11 +121,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
holder.bind(getModel(position))
}

override fun onBindViewHolder(
holder: BindingViewHolder,
position: Int,
payloads: MutableList<Any>
) {
override fun onBindViewHolder(holder: BindingViewHolder, position: Int, payloads: MutableList<Any>) {
if (payloads.isNotEmpty()) {
onPayload?.invoke(holder, payloads[0])
} else {
Expand All @@ -140,13 +134,16 @@ 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

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
this.rv = recyclerView
if (context == null) {
context = recyclerView.context
}
if (touchEnable) itemTouchHelper.attachToRecyclerView(recyclerView)
}

Expand Down Expand Up @@ -464,11 +461,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
}
}

private fun flat(
list: MutableList<Any?>,
expand: Boolean? = null,
@IntRange(from = -1) depth: Int = 0
): MutableList<Any?> {
private fun flat(list: MutableList<Any?>, expand: Boolean? = null, @IntRange(from = -1) depth: Int = 0): MutableList<Any?> {

if (list.isEmpty()) return list
val newList = ArrayList(list)
Expand Down Expand Up @@ -696,10 +689,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
*/
fun setChecked(@IntRange(from = 0) position: Int, checked: Boolean) {

if ((checkedPosition.contains(position) && checked) || (!checked && !checkedPosition.contains(
position
))
) return
if ((checkedPosition.contains(position) && checked) || (!checked && !checkedPosition.contains(position))) return

val itemViewType = getItemViewType(position)

Expand Down Expand Up @@ -755,11 +745,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
* @param depth 递归展开子项的深度, 如等于-1则代表展开所有子项, 0表示仅展开当前
* @return 展开后增加的条目数量
*/
fun expand(
@IntRange(from = 0) position: Int,
scrollTop: Boolean = false,
@IntRange(from = -1) depth: Int = 0
): Int {
fun expand(@IntRange(from = 0) position: Int, scrollTop: Boolean = false, @IntRange(from = -1) depth: Int = 0): Int {
val holder = rv?.findViewHolderForLayoutPosition(position) as? BindingViewHolder ?: return 0
return holder.expand(scrollTop, depth)
}
Expand All @@ -781,11 +767,7 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
* @param depth 递归展开子项的深度, 如等于-1则代表展开所有子项, 0表示仅展开当前
* @return 展开或折叠后变动的条目数量
*/
fun expandOrCollapse(
@IntRange(from = 0) position: Int,
scrollTop: Boolean = false,
@IntRange(from = -1) depth: Int = 0
): Int {
fun expandOrCollapse(@IntRange(from = 0) position: Int, scrollTop: Boolean = false, @IntRange(from = -1) depth: Int = 0): Int {
val holder = rv?.findViewHolderForLayoutPosition(position) as? BindingViewHolder ?: return 0
return holder.expandOrCollapse(scrollTop, depth)
}
Expand All @@ -794,12 +776,14 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()

inner class BindingViewHolder : RecyclerView.ViewHolder {

private var viewDataBinding: ViewDataBinding? = null
lateinit var _data: Any

private set
var context: Context = this@BindingAdapter.context!!
val adapter: BindingAdapter = this@BindingAdapter
val modelPosition get() = layoutPosition - headerCount

private var viewDataBinding: ViewDataBinding? = null

constructor(itemView: View) : super(itemView)

constructor(viewDataBinding: ViewDataBinding) : super(viewDataBinding.root) {
Expand Down Expand Up @@ -840,14 +824,9 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()

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

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

onBind?.invoke(this@BindingViewHolder)
viewDataBinding?.setVariable(modelId, model)
viewDataBinding?.executePendingBindings()
}
Expand All @@ -858,6 +837,11 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
*/
fun <B : ViewDataBinding> getBinding(): B = viewDataBinding as B

/**
* 查找ItemView上的视图
*/
fun <V : View> findView(@IdRes id: Int): V = itemView.findViewById(id)

/**
* 返回数据模型
*/
Expand Down Expand Up @@ -893,9 +877,9 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
if (itemSublist is ArrayList) itemSublist else itemSublist.toMutableList()
val sublistFlat = flat(sublist, true, depth)
(this@BindingAdapter.models as MutableList).addAll(
layoutPosition + 1,
sublistFlat
)
layoutPosition + 1,
sublistFlat
)
if (expandAnimationEnabled) {
notifyItemChanged(layoutPosition)
notifyItemRangeInserted(layoutPosition + 1, sublistFlat.size)
Expand All @@ -904,8 +888,8 @@ class BindingAdapter : RecyclerView.Adapter<BindingAdapter.BindingViewHolder>()
}
if (scrollTop) {
rv?.postDelayed({
rv?.smoothScrollToPosition(layoutPosition)
}, 200)
rv?.smoothScrollToPosition(layoutPosition)
}, 200)
}
sublistFlat.size
}
Expand Down
45 changes: 22 additions & 23 deletions brv/src/main/java/com/drake/brv/PageRefreshLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.drake.brv.listener.OnMultiStateListener
import com.drake.statelayout.StateConfig
import com.drake.statelayout.StateConfig.errorLayout
import com.drake.statelayout.StateLayout
import com.drake.statelayout.Status
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshComponent
import com.scwang.smart.refresh.layout.api.RefreshLayout
Expand Down Expand Up @@ -52,11 +53,11 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
// 监听onBindViewHolder事件
var onBindViewHolderListener = object : OnBindViewHolderListener {
override fun onBindViewHolder(
rv: RecyclerView,
adapter: BindingAdapter,
holder: BindingAdapter.BindingViewHolder,
position: Int
) {
rv: RecyclerView,
adapter: BindingAdapter,
holder: BindingAdapter.BindingViewHolder,
position: Int
) {
if (mEnableLoadMore && !mFooterNoMoreData && preloadIndex != -1 && (adapter.itemCount - preloadIndex <= position)) {
post {
if (state == RefreshState.None) {
Expand Down Expand Up @@ -117,9 +118,9 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {

mEnableLoadMoreWhenContentNotFull = false
mEnableLoadMoreWhenContentNotFull = attributes.getBoolean(
R.styleable.SmartRefreshLayout_srlEnableLoadMoreWhenContentNotFull,
mEnableLoadMoreWhenContentNotFull
)
R.styleable.SmartRefreshLayout_srlEnableLoadMoreWhenContentNotFull,
mEnableLoadMoreWhenContentNotFull
)

emptyLayout =
attributes.getResourceId(R.styleable.PageRefreshLayout_empty_layout, View.NO_ID)
Expand Down Expand Up @@ -167,7 +168,6 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
}

val rv = contentView

if (rv is RecyclerView) {
rv.addOnLayoutChangeListener(OnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
val adapter = rv.adapter
Expand Down Expand Up @@ -207,11 +207,11 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
fun addData(data: List<Any?>?, hasMore: BindingAdapter.() -> Boolean = { true }) {

val rv = contentView as? RecyclerView
?: throw UnsupportedOperationException("PageRefreshLayout require content RecyclerView")
?: throw UnsupportedOperationException("PageRefreshLayout require content RecyclerView")


val adapter = rv.adapter as? BindingAdapter
?: throw UnsupportedOperationException("RecyclerView require use BindingAdapter")
?: throw UnsupportedOperationException("RecyclerView require use BindingAdapter")

val isRefreshState = state == RefreshState.Refreshing

Expand Down Expand Up @@ -288,7 +288,7 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
stateChanged = true
}

val currentState = getState()
val currentState = state

if (success) {
loaded = true
Expand All @@ -304,8 +304,12 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
if (hasMore) finishLoadMore(success) else finishLoadMoreWithNoMoreData()
}

if (currentState != RefreshState.Loading && realEnableLoadMore) {
super.setEnableLoadMore(success)
if (realEnableLoadMore) {
if (stateEnabled && stateLayout?.status != Status.CONTENT) {
super.setEnableLoadMore(false)
} else {
super.setEnableLoadMore(true)
}
}
}

Expand All @@ -331,20 +335,14 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {
*/
var stateEnabled = true
set(value) {

if (!value && !mEnableLoadMore) {
super.setEnableLoadMore(value)
}

field = value
if (finishInflate) {
if (value && stateLayout == null) {
if (field && stateLayout == null) {
replaceStateLayout()
} else if (!value) {
} else if (!field) {
stateLayout?.showContent()
}
}

field = value
}

var emptyLayout = View.NO_ID
Expand Down Expand Up @@ -460,6 +458,7 @@ open class PageRefreshLayout : SmartRefreshLayout, OnRefreshLoadMoreListener {

onRefresh {
if (realEnableRefresh) super.setEnableRefresh(false)
if (realEnableLoadMore) super.setEnableLoadMore(false)
notifyStateChanged(RefreshState.Refreshing)
onRefresh(this@PageRefreshLayout)
}
Expand Down
2 changes: 1 addition & 1 deletion brv/src/main/java/com/drake/brv/item/ItemBind.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ import com.drake.brv.BindingAdapter
* 该接口进行UI操作不符合MVVM架构, 因为Model中不允许出现View引用
*/
interface ItemBind {
fun onBind(vh: BindingAdapter.BindingViewHolder)
fun onBind(holder: BindingAdapter.BindingViewHolder)
}
16 changes: 16 additions & 0 deletions brv/src/main/java/com/drake/brv/utils/BRV.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.drake.brv.utils

object BRV {
/*
即item的layout布局中的<variable>标签内定义变量名称
示例:
<variable
name="m"
type="com.drake.brv.sample.mod.CheckModel" />
则应在Application中的[onCreate]函数内设置:
BindingAdapter.modelId = BR.m
*/
var modelId: Int = -1
}
Loading

0 comments on commit 1b3dd2a

Please sign in to comment.