试图通过EventBus影响RecyclerView项目

时间:2018-07-17 10:09:44

标签: android kotlin greenrobot-eventbus

我正在尝试从回收项目视图类发布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)
}
...

2 个答案:

答案 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 / }

您可以尝试