我正在尝试从回收项目视图类发布EventBus事件,并在同一类中订阅该事件,以便所有回收项目都可以捕获该事件。
现在更详细:
我有一个RecyclerView,其中每个项目(FriendListItem.kt)都有一个上下文菜单。一次只能显示一个上下文菜单。这意味着我需要关闭另一个项目的上下文菜单(如果可见)。
我选择使用我们已经在应用程序中广泛使用的org.greenrobot.eventbus
。在项目类中,当要显示菜单时,我发布一个事件,并将其捕获到同一类中。我以为这样所有的项目都会响应并关闭它们的菜单(可能是可见的),但是事件Subscriber却什么都没有。
我只添加包含的片段按需要注册和注销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)
}
...
答案 0 :(得分:0)
尝试一下。 Kotlin Int发生在我身上,它可能会解决您的问题
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: FriendsListResetOtherMenus?) {
if (menu != null && !menu!!.isShowing)
menu!!.dismiss()
}
答案 1 :(得分:0)
我很少使用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 / }
您可以尝试