活动/片段中的警报对话框确认后,如何在单击时更新RecyclerView按钮状态? [英] How do I update my RecyclerView button state on click after alert dialog confirmation in activity/fragment?

查看:73
本文介绍了活动/片段中的警报对话框确认后,如何在单击时更新RecyclerView按钮状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常独特的情况,我在recyclerview中有一个按钮,单击该按钮(初始状态为"register")后,会将其意图传递给片段或活动中的广播接收器,并在其中引发警报对话框,其中2选项,是或否.如果选择否,则什么也不会发生,并且对话框会消失,但是如果单击是,它将处理我在我的演示者类中定义的功能(与数据有关),并且应该将我的按钮ui状态更新为取消".其他方法也一样,单击取消"将返回警报,单击是"将切换ui文本进行注册.

I have a pretty unique situation, where I have a button in a recyclerview, which upon click (initial state "register"), passes an intent to a broadcast receiver in fragment or activity where it throws an alert dialog , with 2 options, yes or no. If no is selected, nothing happens and the dialog dismisses, but if yes is clicked, it processes a function I defined in my presenter class (related to data) and is supposed to update my button ui state to "cancel". and same goes for the other way around where upon clicking cancel it will bring back alert, and clicking on yes will switch the ui text to register.

现在我已经实现了如下代码(请注意,即使notifydatasetchanged对我也不起作用).知道我做错了什么以及如何实现这一目标吗? 适配器中public void onBind(int position)函数中的代码:

Now I have implemented the code as follows.(please note, even notifydatasetchanged doesnt work for me). Any idea what I am doing wrong and how I can achieve this? code in my public void onBind(int position) function in adapter:

if (repo.getIsRsvpAvailable().equals("true")) {
    rsvpButton.setVisibility(View.VISIBLE);
    for (int i = 0; i < mAllRSVPEventsList.size(); i++) {
        if (mAllRSVPEventsList.get(i).getEvent().getEventId().equals(repo.getEventId()) && mAllRSVPEventsList.get(i).getIsAttending()) {
            rsvpButton.setText("CANCEL");
            rsvpButton.setOnClickListener(v -> {
                Intent in = new Intent("main_rsvp_button_clicked");
                in.putExtra("main_rsvp_event_id", repo.getEventId());
                in.putExtra("main_rsvp_is_attending", "false");
                in.putExtra("main_rsvp_item_position", position);
                rsvpButton.getContext().sendBroadcast(in);
            });
            break;
        } else {
            rsvpButton.setText("RSVP");
            rsvpButton.setOnClickListener(v -> {
                Intent in = new Intent("main_rsvp_button_clicked");
                in.putExtra("main_rsvp_event_id", repo.getEventId());
                in.putExtra("main_rsvp_is_attending", "true");
                in.putExtra("main_rsvp_item_position", position);

                rsvpButton.getContext().sendBroadcast(in);
            });
        }
    }

}

这是我的活动中广播接收器中的相应代码:

Here's the corresponding code in broadcast receiver in my activity :

private BroadcastReceiver mEventIdReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String eventId = intent.getStringExtra(EVENTID_MAIN_EXTRA_TITLE);
            String isAttending = intent.getStringExtra(EVENTID_MAIN_IS_ATTENDING);
            int itemPosition = intent.getIntExtra(EVENTID_MAIN_RSVP_ITEM_POSITION, 0);


            if (isAttending.equals("true")) {
                showDialog(R.string.rsvp_title, R.string.confirm_rsvp_body, R.string.yes,
                        (dialog, which) -> {
                            mPresenter.onRSVPClick(eventId, isAttending);

                            mEventListAdapter.notifyDataSetChanged();
                            mEventRecyclerView.removeAllViews();
                            mEventRecyclerView.scrollToPosition(itemPosition);

                        }, R.string.no, null, null);
            } else {
                showDialog(R.string.rsvp_title, R.string.confirm_cancel_body, R.string.yes,
                        (dialog, which) -> {
                            mPresenter.onRSVPClick(eventId, isAttending);

                            mEventListAdapter.notifyDataSetChanged();
                            mEventRecyclerView.removeAllViews();
                            mEventRecyclerView.scrollToPosition(itemPosition);

                        }, R.string.no, null, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

请注意:mEventListAdapter是我的适配器,我正在使用按钮UI代码,而mEventRecyclerView是我在片段中使用的回收器视图.

Please note: mEventListAdapter is my adapter i am using the button UI code in and mEventRecyclerView is the recycler view i am using in the fragment.

知道我丢失或做错了什么吗? 谢谢!

Any idea what I am missing or doing wrong? Thanks!

RSVPClick方法:

RSVPClick method :

@Override
public void onRSVPClick(String eventId, String isAttending) {
    getMvpView().showLoading();
    getCompositeDisposable().add(getDataManager()
            .doRSVPEventApiCall(
                    eventId,
                    getDataManager().getFirstName(),
                    getDataManager().getLastName(),
                    getDataManager().getCurrentUserEmail(),
                    isAttending
            )
            .subscribeOn(getSchedulerProvider().io())
            .observeOn(getSchedulerProvider().ui())
            .subscribe(response -> {
                if (!isViewAttached()) {
                    return;
                }
                getMvpView().hideLoading();
            }, throwable -> {
                if (!isViewAttached()) {
                    return;
                }
                getMvpView().hideLoading();
                if (throwable instanceof ANError) {
                    ANError anError = (ANError) throwable;
                    handleApiError(anError);
                }
            }));
}

推荐答案

您可以轻松维护一个数组,以指示RecyclerView中每个项目的按钮状态.例如,假设每个按钮有两种状态(即RSVP = 0,Cancel = 1).现在,在您的RecyclerView适配器中声明一个数组,如下所示.

You can easily maintain an array to indicate the state of the buttons of each of your items in the RecyclerView. For example, let us assume there are two states of each button (i.e RSVP = 0, Cancel = 1). Now declare an array in your RecyclerView adapter like the following.

private int[] stateArray; 

在适配器的构造函数中,如下所示初始化数组.让我们假设您的构造函数如下所示.

In the constructor of your adapter, initialize the array like the following. Let us assume your constructor looks like the following.

public EventListAdapter(Context context, ArrayList<Event> eventList) {
    this.eventList = eventList; 
    stateArray = new int[eventList.size];
    initializeTheStateArray(eventList);
}

private void initializeTheStateArray(ArrayList<Event> eventList) {

    // Initialize the array so that we can keep track of the items which are being attended or not. 
    for (int i = 0; i < eventList.size(); i++) {
        if(event.isAttending()) stateArray[i] = 1;
        else stateArray[i] = 0;
    }
}

现在,在onBindViewHolder功能中,根据stateArray的条目设置按钮的文本.这看起来应如下所示.

Now in the onBindViewHolder function, set the text of the button based on the entry of the stateArray. This should look somewhat like the following.

if(stateArray[position] == 1) button.setText("Cancel"); // Because this item is already registerd 
else button.setText("RSVP");

您的适配器需要一些附加功能,以便您可以单击按钮或从API更新时更新stateArray.

You need some additional function in your adapter so that you can update the stateArray on your button click or from an update from the API.

public void updateButtonState(int position, boolean isAttendening) {
    if(isAttending) stateArray[position] = 1;
    else stateArray[position] = 0;
    notifyDataSetChanged(); // Call the notifyDataSetChanged here to see the affect
}

并且在API调用后更新适配器的整个列表时,也请不要忘记更新stateArray.我希望您已经具有更新适配器中事件列表的功能.如下修改功能.

And when you update the whole list of your adapter after an API call, do not forget the update the stateArray as well. I hope you have a function to update the event list in your adapter already. Modify the function like the following.

public void updateEventList(ArrayList<Event> eventList) {
    this.eventList = eventList;
    stateArray = new int[eventList.size()];
    initializeTheStateArray(eventList);
}

现在,单击按钮时,您可以调用适配器的updateButtonState功能.在rsvpButton.setOnClickListener中修改按钮单击动作.

Now you can call updateButtonState function of your adapter when the button is clicked. Modify the button click action in your rsvpButton.setOnClickListener.

如果需要,还可以修改onReceive函数,以在RecyclerView中获得预期的输出.

You can also modify the onReceive function if necessary to get the expected output in your RecyclerView.

希望此设置将帮助您实现所需的预期行为.

Hope this setup will help you to achieve the expected behavior that you want.

最后但并非最不重要的一点是,在onReceive函数中,如果网络调用是异步的,并且将花费一些时间,则您将立即更新RecyclerView,而这对RecyclerView的项目没有影响.从API获取数据.当API调用中的数据可用时,您可以考虑从onRSVPClick方法中调用updateEventList方法.

Last, but not least, in your onReceive function, you are immediately updating the RecyclerView when it will have no effect on the items of the RecyclerView because the network call is asynchronous and will take some time to fetch the data from the API. You might consider calling the updateEventList method from the onRSVPClick method when the data is available from the API call.

希望有帮助!

这篇关于活动/片段中的警报对话框确认后,如何在单击时更新RecyclerView按钮状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆