有时候我们在使用RecycleView
的时候需要在没有数据的时候设置emptyView。这里通过对RecycleView
进行拓展来设置emptyView.本质上是通过有数据时候隐藏RecycleView
显示emptyView,无数据时候通过隐藏emptyView显示RecycleView
来处理的。本例参考腾讯Bugly的代码,但是示例代码有疏漏,所以这里给出原因及解决方式。
布局文件
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_F8F8F8">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.custom.BaseRecycleView
android:id="@+id/make_money_task_mine_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="@dimen/dp_15"
android:visibility="visible"/>
RelativeLayout>
LinearLayout>
kotlin文件
recycleView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL,false)
recycleView.emptyView = layoutInflater.inflate(R.layout.layout_empty_view,rootView,false)
recycleView.adapter = adapter
/**
* 自定义基础的RecycleView
* 内部实现了空视图
*/
class BaseRecycleView : RecyclerView{
var emptyView: View ?= null
set(value) {
field = value
// (this.rootView as ViewGroup).addView(value) //加入主界面布局
val rootViewGroup = this.parent as ViewGroup
rootViewGroup.addView(value)
}
/**
* 数据监测中心
*/
private val adapterDataObserver = object :AdapterDataObserver(){
override fun onChanged() {
adapter?.run {
if(itemCount == 0){
emptyView?.visibility = View.VISIBLE
this@BaseRecycleView.visibility = GONE;
}else{
emptyView?.visibility = View.GONE
this@BaseRecycleView.visibility = VISIBLE
}
}
}
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
super.onItemRangeRemoved(positionStart, itemCount)
onChanged()
}
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
super.onItemRangeMoved(fromPosition, toPosition, itemCount)
onChanged()
}
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount)
onChanged()
}
override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
super.onItemRangeChanged(positionStart, itemCount)
onChanged()
}
override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
super.onItemRangeChanged(positionStart, itemCount, payload)
onChanged()
}
}
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun setAdapter(adapter: Adapter<*>?) {
super.setAdapter(adapter)
if (null == adapter) return
adapter.registerAdapterDataObserver(adapterDataObserver);
adapterDataObserver.onChanged();
}
}
在原代码中将emptyView添加进RecycleView
的方式是通过如下方式
(this.rootView as ViewGroup).addView(value) //加入主界面布局
这种方式只有在布局中只有RecycleView
一个子控件的时候有效,如果在RecycleView
外面还有一层的话,就无法达到这个效果了。因为this.rootView
寻找的是布局的根布局,所以在根布局中添加emptyView后,再隐藏RecycleView
的话,emptyView还是无法显示。所以需要将代码改为以下写法:
val rootViewGroup = this.parent as ViewGroup
rootViewGroup.addView(value)
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_F8F8F8">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.custom.BaseRecycleView
android:id="@+id/make_money_task_mine_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="@dimen/dp_15"
android:visibility="visible"/>
RelativeLayout>
LinearLayout>
腾讯bugly博客园地址:https://www.cnblogs.com/bugly/p/6264751.html
Android之View.getRootView:https://www.cnblogs.com/linux007/p/5783115.html