Android 带多个切换按钮的Recyler视图在滚动上随机检查按钮
我有一个recycler视图,其中有多个切换按钮,单击这些按钮,状态会发生更改,新更新的状态会通过调用一个服务来更改切换按钮的状态发送到服务器。 我面临的问题是,每当滚动recycler视图时,切换按钮都会因为视图的循环而被随机检查,并且服务会同时被调用多次,因此会显示一个不确定的进度条。 我已经尝试了多种方法来处理这个问题,将适配器初始设置为null。以及还存储按钮的选中/切换状态的状态。 但似乎没有任何帮助 下面是recycler适配器类的代码Android 带多个切换按钮的Recyler视图在滚动上随机检查按钮,android,android-recyclerview,recyclerview-layout,Android,Android Recyclerview,Recyclerview Layout,我有一个recycler视图,其中有多个切换按钮,单击这些按钮,状态会发生更改,新更新的状态会通过调用一个服务来更改切换按钮的状态发送到服务器。 我面临的问题是,每当滚动recycler视图时,切换按钮都会因为视图的循环而被随机检查,并且服务会同时被调用多次,因此会显示一个不确定的进度条。 我已经尝试了多种方法来处理这个问题,将适配器初始设置为null。以及还存储按钮的选中/切换状态的状态。 但似乎没有任何帮助 下面是recycler适配器类的代码 public class Notificati
public class NotificationsIllnessAdapter extends RecyclerView.Adapter<NotificationsIllnessAdapter.NotificationIllnessViewHolder> {
Context context = null;
ArrayList<NotificationIllnessdata> notificationIllnessdatas;
ArrayList<NotificationIllnessdata> notificationIllnessArraylist = null;
NetworkStatus mNetworkStatus = null;
static AlertDialog mShowDialog = null;
Button mButton_alerts;
public NotificationsIllnessAdapter(Context context,ArrayList<NotificationIllnessdata> notificationIllnessdataArrayList,Button button_alerts) {
this.context = context;
this.notificationIllnessdatas=notificationIllnessdataArrayList;
this.mButton_alerts=button_alerts;
for(int i=0;i<this.notificationIllnessdatas.size();i++)
{
Log.e("nIllnessadapter","inside constructor"+this.notificationIllnessdatas.get(i).getIsNotification());
}
}
@Override
public NotificationIllnessViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mNetworkStatus = new NetworkStatus(context);
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.notifications_inflater, parent, false);
notificationIllnessArraylist = new ArrayList<>();
NotificationIllnessViewHolder viewHolder = new NotificationIllnessViewHolder(context,v);
viewHolder.setClickListener(new MyClickListener() {
@Override
public void onClickListener(View v, int position, boolean isLongClick) {
Toast.makeText(context,"OnClick",Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(final NotificationIllnessViewHolder holder, final int position) {
holder.mTextView_symptom.setText(notificationIllnessdatas.get(position).getIllnessCategory());
if(notificationIllnessdatas.get(position).getIsNotification())
{
Log.e("nIllnessadapter","true"+position);
holder.mToggleButton_symptom.setChecked(true);
}
else
{
Log.e("nIllnessadapter","false"+position);
holder.mToggleButton_symptom.setChecked(false);
}
//in some cases, it will prevent unwanted situations
holder.mToggleButton_symptom.setOnCheckedChangeListener(null);
//if true the togglebutton will be selected else unselected.
holder.mToggleButton_symptom.setChecked(notificationIllnessdatas.get(position).getIsNotification());
holder.mToggleButton_symptom.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
ArrayList<UpdateNotificationRequestData> Updatenoti;
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
//toggle button enabled
UpdateNotificationsRequestModel requestModel = new UpdateNotificationsRequestModel();
requestModel.setUserID(AppPreferences.readString(context, AppPreferenceNames.sUserid,""));
requestModel.setAppVersion(CommonUtils.APP_VERSION);
requestModel.setDeviceInfo(CommonUtils.DeviceInfo);
requestModel.setDeviceTypeID(CommonUtils.DEVICE_TYPE_ID);
Updatenoti = new ArrayList<UpdateNotificationRequestData>();
UpdateNotificationRequestData requestData = new UpdateNotificationRequestData();
Log.e("illadapter","status-->"+notificationIllnessdatas.get(position).getIsNotification());
requestData.setIsNotification("1");
requestData.setNotificationSettingID(notificationIllnessdatas.get(position).getNotificationSettingID());
Updatenoti.add(requestData);
requestModel.setUpdateNotification(Updatenoti);
/**
* Call the Update Notifications service
*/
if (mNetworkStatus.isNetWorkAvailable(context) == true) {
update_notifications(requestModel);
} else {
CommonUtils.showAlertDialog(context,"No Network Available. Please connect to network");
}
//set the objects last status
holder.mToggleButton_symptom.setChecked(isChecked);
}
else
{
//toggle button disabled
UpdateNotificationsRequestModel requestModel = new UpdateNotificationsRequestModel();
requestModel.setUserID(AppPreferences.readString(context, AppPreferenceNames.sUserid,""));
requestModel.setAppVersion(CommonUtils.APP_VERSION);
requestModel.setDeviceInfo(CommonUtils.DeviceInfo);
requestModel.setDeviceTypeID(CommonUtils.DEVICE_TYPE_ID);
Updatenoti = new ArrayList<UpdateNotificationRequestData>();
UpdateNotificationRequestData requestData = new UpdateNotificationRequestData();
Log.e("illadapter","status 2-->"+notificationIllnessdatas.get(position).getIsNotification());
requestData.setIsNotification("0");
requestData.setNotificationSettingID(notificationIllnessdatas.get(position).getNotificationSettingID());
Updatenoti.add(requestData);
requestModel.setUpdateNotification(Updatenoti);
/**
* Call the UpdateNotifications service
*/
if (mNetworkStatus.isNetWorkAvailable(context) == true) {
update_notifications(requestModel);
} else {
CommonUtils.showAlertDialog(context,"No Network Available. Please connect to network");
}
//set the objects last status
holder.mToggleButton_symptom.setChecked(false);
}
}
});
}
@Override
public int getItemCount() {
return notificationIllnessdatas.size();
}
/**
* View Holder for Adapter
*/
class NotificationIllnessViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
MyClickListener clickListener;
public TextView mTextView_symptom;
public ToggleButton mToggleButton_symptom;
public NotificationIllnessViewHolder(Context context,View itemView) {
super(itemView);
mTextView_symptom = (TextView)itemView.findViewById(R.id.TextView_Symptom);
mToggleButton_symptom = (ToggleButton) itemView.findViewById(R.id.ToggleButton_Symptoms);
}
@Override
public void onClick(View v) {
// If not long clicked, pass last variable as false.
clickListener.onClickListener(v, getPosition(), false);
}
public void setClickListener(MyClickListener clickListener) {
this.clickListener = clickListener;
}
}
/**
* Update the notification settings
*/
public void update_notifications(UpdateNotificationsRequestModel object) {
/**
* Start the progress Bar.
*/
CommonUtils.show_progressbar(context);
/**
* call api
*/
Call<UpdateNotificationsResponseModel> responsecall = VirusApplication.getRestClient().getAPIService().updateNotifications(object);
responsecall.enqueue(new Callback<UpdateNotificationsResponseModel>() {
@Override
public void onResponse(Response<UpdateNotificationsResponseModel> response, Retrofit retrofit) {
/**
* Stop the progress Bar
*/
CommonUtils.stop_progressbar();
if (response.isSuccess()) {
//Server Success
UpdateNotificationsResponseModel responseModel = response.body();
if (responseModel.getErrorCode().equalsIgnoreCase("0")) {
//Data Success
Log.e("nf", "data success");
//CommonUtils.showAlertDialog(context, responseModel.getMessage());
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(responseModel.getMessage())
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
/**
* Downloads mychildren details.
*/
if (mNetworkStatus.isNetWorkAvailable(context)) {
getNotificationSettings();
} else {
CommonUtils.showAlertDialog(context, context.getString(R.string.network_unavailable));
}
dialog.dismiss();
}
});
mShowDialog = builder.create();
mShowDialog.show();
} else {
CommonUtils.showAlertDialog(context, responseModel.getMessage());
}
} else {
CommonUtils.showAlertDialog(context, "Server Error");
}
}
@Override
public void onFailure(Throwable t) {
/**
* Stop the progress Bar
*/
CommonUtils.stop_progressbar();
}
});
}
/**
* Get Notification Settings
*/
public void getNotificationSettings(){
//hit the getnotifications API to fetch the notification details
CommonUtils.show_progressbar(context);
/**
* Calls WebAPI
*/
Call<NotificationsModel> notificationsModelCall = VirusApplication.getRestClient().getAPIService().notifications(getNotificationsrequest());
notificationsModelCall.enqueue(new Callback<NotificationsModel>() {
@Override
public void onResponse(Response<NotificationsModel> response, Retrofit retrofit) {
/**
* Stops the Progresss bar
*/
CommonUtils.stop_progressbar();
if(response.isSuccess()) {
NotificationsModel notificationsModel = response.body();
if (notificationsModel.getErrorCode().equalsIgnoreCase("0")) {// Data Success
Log.e("notificationsAdapter","data success");
int i = 1;
notificationIllnessArraylist.clear();
for (NotificationIllnessdata notificationIllnessdata : notificationsModel.getNotificationIllnessdata()) {
notificationIllnessArraylist.add(notificationIllnessdata);
Log.e("notificationsAdapter","getnotificationsmethod"+i +notificationIllnessdata.getIsNotification() );
i++;
}
Log.e("sonu", "Symptoms ArraySize-->" + notificationIllnessArraylist.size());
if (notificationIllnessArraylist.size() > 0) {
ArrayList<NotificationIllnessdata> arrayTrue = new ArrayList<NotificationIllnessdata>();
ArrayList<NotificationIllnessdata> arrayFalse = new ArrayList<NotificationIllnessdata>();
for(int j=0;j<notificationIllnessArraylist.size();j++)
{
if(notificationIllnessArraylist.get(j).getIsNotification()){
arrayTrue.add(notificationIllnessArraylist.get(j));
}
else
if(!notificationIllnessArraylist.get(j).getIsNotification())
{
arrayFalse.add(notificationIllnessArraylist.get(j));
}
}
if(notificationIllnessArraylist.size()==arrayTrue.size())
{
mButton_alerts.setText("DeSelect All");
mButton_alerts.setBackgroundResource(R.drawable.togglebutton_on);
}
else
if(notificationIllnessArraylist.size()==arrayFalse.size())
{
mButton_alerts.setText("Select All");
mButton_alerts.setBackgroundResource(R.drawable.togglebutton_off);
}
else {
mButton_alerts.setText("Select All");
mButton_alerts.setBackgroundResource(R.drawable.togglebutton_off);
}
}
}
}
}
@Override
public void onFailure(Throwable t) {
}
});
}
/**
* Request values to Get notifications.
*
* @return map object
*/
public Map<String, Object> getNotificationsrequest() {
Map<String, Object> getChildrenValues = new HashMap<>();
getChildrenValues.put("appVersion", CommonUtils.APP_VERSION);
getChildrenValues.put("deviceTypeID", CommonUtils.DEVICE_TYPE_ID);
getChildrenValues.put("deviceInfo", CommonUtils.DeviceInfo);
getChildrenValues.put("userID", AppPreferences.readString(context, AppPreferenceNames.sUserid, ""));
return getChildrenValues;
}
}
公共类NotificationSillMessageAdapter扩展了RecyclerView.Adapter{
Context=null;
ArrayList Notificationillness数据;
ArrayList notificationIllnessArraylist=null;
网络状态mNetworkStatus=null;
静态AlertDialog mShowDialog=null;
按钮mButton_警报;
公共通知SillMessageAdapter(上下文上下文、ArrayList notificationIllnessdataArrayList、按钮警报){
this.context=上下文;
this.notificationIllnessdatas=notificationillnessdatararyList;
此.mButton\u警报=按钮\u警报;
对于(int i=0;i 0){
ArrayList arrayTrue=新的ArrayList();
ArrayList arrayFalse=新的ArrayList();
对于(int j=0;j试一下:
public class NotificationsIllnessAdapter extends RecyclerView.Adapter<NotificationsIllnessAdapter.NotificationIllnessViewHolder> {
Context context = null;
ArrayList<NotificationIllnessdata> notificationIllnessdatas;
NetworkStatus mNetworkStatus = null;
static AlertDialog mShowDialog = null;
Button mButton_alerts;
public NotificationsIllnessAdapter(Context context,ArrayList<NotificationIllnessdata> notificationIllnessdataArrayList,Button button_alerts) {
this.context = context;
this.mNetworkStatus = new NetworkStatus(context);
this.notificationIllnessdatas=notificationIllnessdataArrayList;
this.mButton_alerts=button_alerts;
}
@Override
public NotificationIllnessViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.notifications_inflater, parent, false);
NotificationIllnessViewHolder viewHolder = new NotificationIllnessViewHolder(context,v);
return viewHolder;
}
@Override
public void onBindViewHolder(final NotificationIllnessViewHolder holder, final int position) {
holder.mTextView_symptom.setText(notificationIllnessdatas.get(position).getIllnessCategory());
holder.mToggleButton_symptom.setChecked(notificationIllnessdatas.get(position).getIsNotification());
holder.mToggleButton_symptom.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
ArrayList<UpdateNotificationRequestData> Updatenoti;
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int position = getAdapterPosition();
if( position == RecyclerView.NO_POSITION ) {
return;
}
if(isChecked)
{
notificationIllnessdatas.get(position).setNotification(true);
}
else
{
notificationIllnessdatas.get(position).setNotification(false);
}
}
});
}
公共类NotificationSillMessageAdapter扩展了RecyclerView.Adapter{
Context=null;
ArrayList Notificationillness数据;
网络状态mNetworkStatus=null;
静态AlertDialog mShowDialog=null;
按钮mButton_警报;
公共通知SillMessageAdapter(上下文上下文、ArrayList notificationIllnessdataArrayList、按钮警报){
this.context=上下文;
this.mNetworkStatus=新网络状态(上下文);
this.notificationIllnessdatas=notificationillnessdatararyList;
此.mButton\u警报=按钮\u警报;
}
@凌驾
public NotificationIllnessViewHolder onCreateViewHolder(视图组父级,int-viewType){
视图v=LayoutInflater.from(parent.getContext()).inflate(R.layout.notifications\u inflater,parent,false);
NotificationIllnessViewHolder-viewHolder=新的NotificationIllnessViewHolder(上下文,v);
返回视图持有者;
}
@凌驾
BindViewHolder上的公共无效(最终通知illnessViewHolder,最终int位置){
holder.mTextView_symptom.setText(notificationIllnessdatas.get(position.getIllnessCategory());
holder.mToggleButton_symptom.setChecked(notificationIllnessdatas.get(position.getIsNotification());
holder.mToggleButton_symptom.setOnCheckedChangeListener(新建CompoundButton.OnCheckedChangeListener()){
ArrayList Updatenoti;
@凌驾
检查更改后的公共无效(复合按钮视图,布尔值已检查){
int position=getAdapterPosition();
如果(位置==RecyclerView.NO_位置){
返回;
}
如果(已检查)
{
notificationIllnessdatas.get(position).setNotification(true);
}
其他的
{
notificationIllnessdatas.get(position).setNotification(false);
}
}
});
}
复选框/切换按钮的切换是由于您的模型类中没有维护状态这一事实而发生的。您的模型类中已经有一个isNotification字段,请按照我在代码中的说明在切换发生时立即设置它。我有其他代码清理建议,但这些建议可以等待
如果你需要更多的澄清,请告诉我
更新:答案仅适用于切换的保留状态
纽扣
为什么不实现click事件和onClick()而不是check changed呢检查按钮状态。谢谢你的代码。我试过了,但我仍然面临着同样的问题。截至我观察到的情况,这是因为两个服务调用同时发生,因为不同的切换按钮在滚动条上被检查。请你能帮帮忙吗?我使用的是回收器视图,所以当视图被回收时e按钮丢失。这是因为视图的循环使用,您需要在模型类中维护切换按钮的状态。是否绝对有必要在按钮发生切换时立即进行网络调用?您不能使用外部按钮触发它吗?因为我们在每次循环使用视图时都有一个检查更改触发器,所以网络调用l发生//设置对象的上次状态保持器。mToggleButton\u症状。setChecked(isChecked);我已通过此语句保存对象的上次状态。切换按钮后,需要立即进行网络调用。