试图通过 EventBus 影响 RecyclerView 项目
Trying to impact RecyclerView items via EventBus
我正在尝试 post 来自回收站项目视图的 EventBus 事件 class 并在同一个 class 中订阅它,以便所有回收站都能获取该事件项目。
现在更详细:
我有一个 RecyclerView,其中每个项目 (FriendListItem.kt) 都有一个上下文菜单。一次只能显示一个上下文菜单。这意味着我需要关闭另一个项目的上下文菜单(如果它可见)。
我选择使用我们已经在我们的应用程序中广泛使用的 org.greenrobot.eventbus
。在项目class中,当要显示菜单时,我post一个事件,并在同一个class中抓取它。我认为这样所有项目都会响应并关闭它们的(可能可见的)菜单,但是事件订阅者不会获取任何东西。
我将补充一点,包含的片段会按应有的方式注册和注销 EventBus,因为它在另一个事件中工作正常。
这里的问题可能是应该在回收站项目视图中抓取事件,该视图显示在多个项目中。会不会是这样?
这是项目:
package com.myapp.android.common.social.friends
import android.content.Context
import android.text.Spanned
import android.view.View
import android.view.View.OnClickListener
import android.widget.ImageView
import android.widget.LinearLayout
import com.myapp.android.common.R
import com.myapp.android.common.database.room.entities.User
import com.myapp.android.common.generic.coachmark.BubbleCoachMark
import com.myapp.android.common.image.ImageSize
import com.myapp.android.common.social.friends.events.FriendsListResetOtherMenus
import kotlinx.android.synthetic.main.friends_list_item.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class FriendsListItem(context: Context) : LinearLayout(context) {
private var user: User? = null
private var menu: BubbleCoachMark? = null
init {
View.inflate(context, R.layout.friends_list_item, this)
}
fun updateView(user: User, sp: Spanned?) {
this.user = user
// Avatar
if (user.pictureUrl != "") {
setUserPicture(user.pictureUrl + "", user.isPremium)
}
// Premium
when {
user.isPremium -> friendPremium.visibility = View.VISIBLE
else -> friendPremium.visibility = View.GONE
}
// Name
when (sp) {
null -> friendName!!.text = user.name
else -> friendName!!.text = sp
}
// Friend Status
invite.visibility = View.GONE
action.visibility = View.VISIBLE
when (user.status) {
User.Status.friend -> {
action.setImageResource(R.drawable.ic_friend_options)
action.setOnClickListener(OnClickListener {
EventBus.getDefault().post(FriendsListResetOtherMenus())
when (menu) {
null -> {
menu = BubbleCoachMark(BubbleCoachMark.BubbleCoachMarkBuilder(context, action, FriendsListItemMenu(context)).setShowBelowAnchor(true))
menu!!.show()
}
else -> {
if (!menu!!.isShowing)
menu!!.show()
}
}
})
}
User.Status.pending -> {
action.setImageResource(R.drawable.ic_friend_requested)
}
User.Status.nofriend -> {
action.setImageResource(R.drawable.ic_friend_add)
}
else -> {
invite.visibility = View.VISIBLE
action.visibility = View.GONE
}
}
}
fun setUserPicture(pictureUrl: String, isPremium: Boolean) {
synchronized(this) {
friendAvatar!!.scaleType = ImageView.ScaleType.CENTER_CROP
friendAvatar!!.setUserPicture(pictureUrl, isPremium, R.drawable.profile_silhuette_new, ImageSize.thumbnail)
}
}
// The method here is not grabbing the event
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: FriendsListResetOtherMenus) {
if (menu != null && !menu!!.isShowing)
menu!!.dismiss()
}
}
更新的解决方案:
在init
子句中本地注册了EventBus:
...
init {
View.inflate(context, R.layout.friends_list_item, this)
EventBus.getDefault().register(this@FriendsListItem)
}
...
取消注册 onDetachedFromWindow
事件中的 EventBus:
...
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
EventBus.getDefault().unregister(this@FriendsListItem)
}
...
试试这个。我遇到了 kotlin Int,它可能会解决你的问题
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: FriendsListResetOtherMenus?) {
if (menu != null && !menu!!.isShowing)
menu!!.dismiss()
}
我很少使用 EventBus,更喜欢 RxBus:
object RxBus {
private val bus = PublishSubject.create<Any>()
fun send(event: Any) {
bus.onNext(event)
}
fun <T> observeEvent(type: Class<T>): Observable<T> =
bus.ofType(type)
}
class NeedToUpdateEvent
发送事件:
RxBus.send(NeedToUpdateEvent())
订阅活动:
RxBus.observeEvent(NeedToUpdateEvent::class.java)
.subscribe { / some action / }
你可以试试这个
我正在尝试 post 来自回收站项目视图的 EventBus 事件 class 并在同一个 class 中订阅它,以便所有回收站都能获取该事件项目。
现在更详细:
我有一个 RecyclerView,其中每个项目 (FriendListItem.kt) 都有一个上下文菜单。一次只能显示一个上下文菜单。这意味着我需要关闭另一个项目的上下文菜单(如果它可见)。
我选择使用我们已经在我们的应用程序中广泛使用的 org.greenrobot.eventbus
。在项目class中,当要显示菜单时,我post一个事件,并在同一个class中抓取它。我认为这样所有项目都会响应并关闭它们的(可能可见的)菜单,但是事件订阅者不会获取任何东西。
我将补充一点,包含的片段会按应有的方式注册和注销 EventBus,因为它在另一个事件中工作正常。
这里的问题可能是应该在回收站项目视图中抓取事件,该视图显示在多个项目中。会不会是这样?
这是项目:
package com.myapp.android.common.social.friends
import android.content.Context
import android.text.Spanned
import android.view.View
import android.view.View.OnClickListener
import android.widget.ImageView
import android.widget.LinearLayout
import com.myapp.android.common.R
import com.myapp.android.common.database.room.entities.User
import com.myapp.android.common.generic.coachmark.BubbleCoachMark
import com.myapp.android.common.image.ImageSize
import com.myapp.android.common.social.friends.events.FriendsListResetOtherMenus
import kotlinx.android.synthetic.main.friends_list_item.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class FriendsListItem(context: Context) : LinearLayout(context) {
private var user: User? = null
private var menu: BubbleCoachMark? = null
init {
View.inflate(context, R.layout.friends_list_item, this)
}
fun updateView(user: User, sp: Spanned?) {
this.user = user
// Avatar
if (user.pictureUrl != "") {
setUserPicture(user.pictureUrl + "", user.isPremium)
}
// Premium
when {
user.isPremium -> friendPremium.visibility = View.VISIBLE
else -> friendPremium.visibility = View.GONE
}
// Name
when (sp) {
null -> friendName!!.text = user.name
else -> friendName!!.text = sp
}
// Friend Status
invite.visibility = View.GONE
action.visibility = View.VISIBLE
when (user.status) {
User.Status.friend -> {
action.setImageResource(R.drawable.ic_friend_options)
action.setOnClickListener(OnClickListener {
EventBus.getDefault().post(FriendsListResetOtherMenus())
when (menu) {
null -> {
menu = BubbleCoachMark(BubbleCoachMark.BubbleCoachMarkBuilder(context, action, FriendsListItemMenu(context)).setShowBelowAnchor(true))
menu!!.show()
}
else -> {
if (!menu!!.isShowing)
menu!!.show()
}
}
})
}
User.Status.pending -> {
action.setImageResource(R.drawable.ic_friend_requested)
}
User.Status.nofriend -> {
action.setImageResource(R.drawable.ic_friend_add)
}
else -> {
invite.visibility = View.VISIBLE
action.visibility = View.GONE
}
}
}
fun setUserPicture(pictureUrl: String, isPremium: Boolean) {
synchronized(this) {
friendAvatar!!.scaleType = ImageView.ScaleType.CENTER_CROP
friendAvatar!!.setUserPicture(pictureUrl, isPremium, R.drawable.profile_silhuette_new, ImageSize.thumbnail)
}
}
// The method here is not grabbing the event
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: FriendsListResetOtherMenus) {
if (menu != null && !menu!!.isShowing)
menu!!.dismiss()
}
}
更新的解决方案:
在init
子句中本地注册了EventBus:
...
init {
View.inflate(context, R.layout.friends_list_item, this)
EventBus.getDefault().register(this@FriendsListItem)
}
...
取消注册 onDetachedFromWindow
事件中的 EventBus:
...
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
EventBus.getDefault().unregister(this@FriendsListItem)
}
...
试试这个。我遇到了 kotlin Int,它可能会解决你的问题
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: FriendsListResetOtherMenus?) {
if (menu != null && !menu!!.isShowing)
menu!!.dismiss()
}
我很少使用 EventBus,更喜欢 RxBus:
object RxBus {
private val bus = PublishSubject.create<Any>()
fun send(event: Any) {
bus.onNext(event)
}
fun <T> observeEvent(type: Class<T>): Observable<T> =
bus.ofType(type)
}
class NeedToUpdateEvent
发送事件:
RxBus.send(NeedToUpdateEvent())
订阅活动:
RxBus.observeEvent(NeedToUpdateEvent::class.java)
.subscribe { / some action / }
你可以试试这个