如何关闭 recyclerview 适配器中的本地广播侦听器?有没有更好的方法来与从它调用的 activity 进行通信?

How can I turn off localbroadcast listener in recyclerview adapter? Of is there a better way to communicate with an activity called from it?

我是 SO 的新手,也是编码的新手,所以如果我在这里违反规则或期望,请提前接受我的道歉。

我有一个涉及两个 recyclerView 的不寻常设置,我将在此处解释并粘贴下面代码的简化版本(因为与此问题无关)。

在我称之为 verticalRecyclerViewActivity 的地方,一个 verticalRecyclerViewAdapter 被调用,它从 Firebase 获取数据并加载到 arrayLists 中。

如果用户单击垂直 Recyclerview 中的一个项目,我将调用 horizo​​ntalRecyclerViewDialogFragment 的新对话框片段被膨胀,并加载我将称为 horizo​​ntalRecyclerView 的内容(它具有与垂直的项目类似的项目,在更多详细信息,并带有单击它们以查看它们的选项)。

如果用户单击 horizo​​ntalRecyclerView 中的某个项目,则会启动一个新的 activity,我将其称为 reviewItem(通过 Intent)。当用户提交他们的评论时,它完成并 returns (通过后台)到水平的 RecyclerView。如果他们在没有实际提交评论的情况下按下后退按钮,也会发生这种情况。一切正常,但我 需要 horizo​​ntalRecyclerView 来显示他们已经(或没有)审查该项目并说明他们在审查中给它的分数。

调用 notifyDataSetChanged 对此不起作用,因为信息是通过两个 recyclerViews 和 Firebase 调用传递的(或者,至少,它会非常低效)。

我试过使用 startActivityForResult(我知道它已被弃用,但如果我可以让它工作,我可以尝试使用我还不明白的更新的等价物)但问题是结果返回到原始的 (VerticalRecylcerView) activity,它是两个 recyclerView 适配器和一个下面需要更新的片段,我不知道如何将该数据传递给水平 Recyclerview。

我也尝试过使用接口,但无法通过 Intent 传递它(尝试使用 Parcelable 和 Serializable,但在这种情况下似乎都不起作用?)。

由于评论是在 Firebase 上更新的,我可以让水平的 Recyclerview 监听变化,但这似乎很低效?

所以我找到了一个使用 localBroadcast 的解决方案(我知道它也被弃用了)。在水平 recyclerView 适配器中审查和接收 Intent(带有审查分数)时传输。但是 我应该何时以及如何注销适配器? 理想情况下,接收器会在用户查看 activity 时打开,并在用户 returns 时关闭。从那个 activity 和(水平的)recyclerView holder 更新,评论是否成功提交,或者用户是否只是按下后退按钮而从未提交评论。

我的问题与这个类似:How to unregister and register BroadcastReceiver from another class?

这是一个副本:How to unregister and register BroadcastReceiver from another class?

这些问题中有很多我不明白,但我认为他们的案例和我的案例之间的重要区别在于,我只是希望接收者知道评论何时提交,最好是取消注册,或者可能是当 viewHolder 被回收时,我试过了但也没有用,因为它没有连接到 viewHolder(应该是吗?)。

非常感谢任何帮助,谢谢!

public class verticalRecyclerViewActivity extends AppCompatActivity {
            
// Loads an XML file and assembles an array from Firebase. 
            
mVerticalRecyclerView = findViewById(R.id.verticalRecyclerView);
            
verticalRecyclerViewAdaptor mVerticalRecyclerViewAdaptor  = new verticalRecyclerViewAdaptor (this); // also pass other information it needs
        
            
mVerticalRecyclerView .setAdapter(mVerticalRecyclerViewAdaptor);

}
        
        
public class verticalRecyclerViewAdaptor extends RecyclerView.Adapter<verticalRecyclerViewAdaptor.singleHolder> {
        
// Usual recyclerView content
        
holder.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

horizontalRecyclerViewFragment  mHorizontalRecyclerViewFragment = new horizontalRecyclerViewFragment();  

// lots of arguments passed it needs. 
        
FragmentManager fragmentManager = ((FragmentActivity) view.getContext()).getSupportFragmentManager();
        
mHorizontalRecyclerViewFragment.show(fragmentManager, null);
                                    
}
    
public class mHorizontalRecyclerViewFragment extends DialogFragment {
    
public Dialog onCreateDialog(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
    
mContext = getActivity().getApplicationContext(); // Not sure why I need this, but it works. 
    
View horizontalRecyclerViewView = getActivity().getLayoutInflater().inflate(R.layout.horizontal_recyclerview_holder, new CardView(getActivity()), false);

Dialog horizontalRecyclerViewDialog = new Dialog(getActivity());
            
horizontalRecyclerViewDialog.setContentView(horizontalRecyclerViewView);

mHorizontalRecyclerView = horizontalRecyclerViewView.getRootView().findViewById(R.id.horizontalRecyclerView);    
    
mHorizontalRecyclerViewAdapter  = new horizontalRecyclerViewAdapter (mContext) 
// Other arguments passed
    
mHorizontalRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), 

LinearLayoutManager.HORIZONTAL, false));

mHorizontalRecyclerView.setAdapter(mHorizontalRecyclerViewAdapter);
          
}
    
public class horizontalRecyclerViewAdapter extends RecyclerView.Adapter<horizontalRecyclerViewAdapter.horizontalRecyclerViewHolder> {
    
    
public horizontalRecyclerViewAdapter(){}
    
// Blank constructor and also one with lots of arguments for it to work. 
    
public horizontalRecyclerViewAdapter.horizontalRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_recyclerview_adaptor_holder, parent, false);

return new horizontalRecyclerViewAdapter.horizontalRecyclerViewHolder(view);

}
    
public void onBindViewHolder(@NonNull horizontalRecyclerViewHolder holder, int position) {
    
    
// Connect up various views. 
    
holder.setOnClickListener(new View.OnClickListener() {
                
@Override
public void onClick(View view) {
    
LocalBroadcastManager.getInstance(mContext).registerReceiver(reviewSubmittedListener, new IntentFilter("reviewSubmitted"));
    
Intent reviewNow = new Intent(view.getContext(), ReviewActivity.class);
    
// Put extra details with the intent
    
view.getContext().startActivity(reviewNow);
    
}
    
BroadcastReceiver reviewSubmittedListener = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent reviewFinishedIntent) {
                       
int reviewScore = reviewFinishedIntent.getExtras().getInt("reviewScore");
                        

// Update the horizontal RecyclerView with the information received from the review Activity. 

}
};

}
    
public class ReviewActivity extends AppCompatActivity {
    
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_review_item);
    
// Set up the review, using Firebase and data passed through the intent.  
    
}
    
public void submitReview() {
    
// Check that the review is complete/valid and submit it through Firebase
    
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(ReviewItemActivity.this);

Intent reviewFinishedIntent = new Intent("reviewSubmitted");
    
reviewFinishedIntent.putExtra("reviewScore", overallScore);

    
LocalBroadcastManager.getInstance(this).sendBroadcast(reviewFinishedIntent);
    
finish();
    
}

如果你正在使用 RxJava 你可以使用 RxBus 否则你可以使用许多 EventBus 对此的实施。

如果这不是您想要采用的路径,那么您可以拥有一个仅可用于片段之间通信的共享视图模型对象,请参阅 this 文章。