1

У меня есть просмотр recycler с несколькими кнопками переключения, по клику которых состояние изменено, а недавно обновленное состояние отправлено на сервер, вызвав службу на изменение состояние кнопки переключения. Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда просматривается просмотр ресайклера, переключающие кнопки получают случайным образом выбор из-за повторной обработки представлений, и служба вызывается несколько раз в то же время, из-за чего отображается неопределенный индикатор выполнения. Я пробовал несколько способов справиться с этим, установив сетевой адаптер в нуль. а также сохранение состояния контролируемого/переключающего состояния кнопки. Но ничего не помогает.Recyler View с несколькими кнопками переключения, случайно проверяя кнопку на прокрутке

Ниже приведен код класса утилизатор адаптера

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; 

    } 


    } 

Пожалуйста, помогите мне с этим. Пробовали много дней, но не нашли решения даже после нескольких ответов на переполнение стека.

+0

Вместо проверки изменилось, почему вы не используете событие click и ** onClick() ** проверьте состояние кнопки. –

ответ

1

Попробуйте это:

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); 

       } 
      } 

     }); 
    } 

переключение флажков кнопки/тумблеры происходит из-за того, что государства не поддерживается в вашем классе модели. У вас уже есть поле isNotification в вашем классе модели, установите его, как только переключится, как я проиллюстрировал в коде. У меня есть другие рекомендации по очистке кода, но они могут подождать.

Сообщите мне, если вам нужно больше разъяснений.

Обновление: Ответ применяется только для удерживающих состояний переключателей кнопок.

+0

Спасибо за код. Я попробовал, но все же я столкнулся с той же проблемой. Что касается того, что я заметил, что это происходит, потому что два вызова службы происходят одновременно из-за того, что разные переключающие кнопки проверяются на свитке. пожалуйста, можете ли вы помочь? –

+0

Я использую просмотр recycler, поэтому, когда представления возвращаются, состояние кнопок теряется. –

+0

Из-за повторной обработки просмотров вам необходимо поддерживать состояния вашей кнопки переключения в классе модели. –