【问题标题】:Android setOnCheckedChangeListener runs twiceAndroid setOnCheckedChangeListener 运行两次
【发布时间】:2016-07-06 09:37:20
【问题描述】:

这是我的代码。什么是原因?

holder.favorite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                addFavorite(famous);
            } else {
                deleteFavorite(famous);
            }
        }
    });

isChecked=true 时,首先运行addFavorite(),然后运行deleteFavorite()

isChecked=false 时,首先运行deleteFavorite(),然后运行addFavorite()

不知道为什么……

编辑:当我向下/向上滚动我的ListView 时,它也会调用这些方法......很奇怪......

    private void deleteFavorite(final FamousTop40Ranking famous) {
        DeleteFavoriteData data = new DeleteFavoriteData(famous.getId());
        FavoriteDeleteApi.Factory.getInstance().deleteFavorite(data.getData())
                .enqueue(new Callback<StatusInfoModel>() {
                    @Override
                    public void onResponse(Call<StatusInfoModel> call, Response<StatusInfoModel> response) {
                        showToast(mActivity, "Famous deleted from your Favorites list.");
                        famous.setFollowersCountry(famous.getFollowersCountry() - 1);
                        famous.setFollowersWorld(famous.getFollowersWorld() - 1);
                        notifyDataSetChanged();
                    }

                    @Override
                    public void onFailure(Call<StatusInfoModel> call, Throwable t) {
                        Log.d("deleteFavorite", mActivity.getString(R.string.something_went_wrong) + t.getMessage());
                    }
                });
    }




private void addFavorite(final FamousTop40Ranking famous) {
        FavoriteCountApi.Factory.getInstance().countFavorites()
                .enqueue(new Callback<CountFavoriteModel>() {
                    @Override
                    public void onResponse(Call<CountFavoriteModel> call, Response<CountFavoriteModel> response) {
                        if (response.isSuccessful()) {
                            if (response.body().getCount() < 20) {
                                FavoriteAddApi.Factory.getInstance().addFavorite(String.valueOf(famous.getId()))
                                        .enqueue(new Callback<StatusInfoModel>() {
                                            @Override
                                            public void onResponse(Call<StatusInfoModel> call, Response<StatusInfoModel> response) {
                                                showToast(mActivity, "Famous added from your Favorites list.");
                                                famous.setFollowersCountry(famous.getFollowersCountry() + 1);
                                                famous.setFollowersWorld(famous.getFollowersWorld() + 1);
                                                notifyDataSetChanged();
                                            }

                                            @Override
                                            public void onFailure(Call<StatusInfoModel> call, Throwable t) {
                                                Log.d("addFavorite", mActivity.getString(R.string.something_went_wrong) + t.getMessage());
                                            }
                                        });
                            } else {
                                showToast(mActivity, mActivity.getString(R.string.reached_max_favorites));
                            }
                        }
                    }

                    @Override
                    public void onFailure(Call<CountFavoriteModel> call, Throwable t) {
                        Log.d("countFavorite", mActivity.getString(R.string.something_went_wrong) + t.getMessage());
                    }
                });
    }

getView()方法:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;

    if(convertView == null) {
        LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.list_view_ranking_famous_single_item, parent, false);
    }

    final FamousTop40Ranking famous = famousModelList.get(position);

    holder = new ViewHolder(convertView);

    holder.name.setText(famous.getName());
    if (mTab == 0) { // RankingFamousMainFragment.TAB_FAMOUS
        holder.followers.setText(String.valueOf(famous.getFollowersWorld()));
    } else {
        holder.followers.setText(String.valueOf(famous.getFollowersCountry()));
    }

    if (famous.getIsFavorite().get(0).getFavorite().equals("1")) {
        holder.favorite.setChecked(true);
    } else {
        holder.favorite.setChecked(false);
    }

    Glide
            .with(mActivity)
            .load(famous.getPhoto())
            .fallback(R.drawable.bg_gradient)
            .error(R.drawable.bg_gradient)
            .centerCrop()
            .crossFade()
            .into(holder.photo);

    holder.favorite.setOnCheckedChangeListener(null);
    holder.favorite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                addFavorite(famous);
            } else {
                deleteFavorite(famous);
            }
        }
    });

    convertView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showToast(mActivity, mActivity.getString(R.string.famous_clicked, position));
        }
    });

    return convertView;
}

【问题讨论】:

    标签: android listview checkbox


    【解决方案1】:

    在 getView 中。将 setonCChecked(null) 移到 if/else 之前。

    之所以如此,是因为 getView 可能会被调用很多次,在这种情况下,我认为它被调用是因为当您更改状态(选中/取消选中)时,它会重绘按钮。在您的 getView 中,您正在调用 setChecked 来触发侦听器。在调用 holder.favorite.setChecked(true/false) 之前将侦听器设置为 null 不会双重触发它。

    关于上/下问题 - 相同,当视图位于屏幕上时,它会被删除。当它再次出现时,它调用 getView 触发一切,因为 holder.favorite.setChecked(true) 激活了 onCheckChangedLIsener

    举个例子:

    holder.favorite.setOnCheckedChangeListener(null);
    holder.favorite.setChecked(true);
    holder.favourite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // handle your logic
            }
        });
    

    【讨论】:

      【解决方案2】:

      我可能迟到了!.. 但这是我修复单选按钮双触发的方法,在我的例子中,我有一个 RadioGroup,它有助于一组单选按钮的行为。

      当您单击特定单选按钮时,您希望在“setOnCheckedChangeListener”中触发 lambda 表达式,这是正常的。

      但是当你“重置”组并且不需要选择单选按钮时,你通常调用:

      radioGroup.clearCheck()
      

      radioGroup.check(-1)
      

      但是当你这样做时,监听器会收到 2 个调用,第一个是用于“未选中”的单选按钮, 单选按钮 ID 的第二个调用等于 -1。

      所以,ai 所做的,对我有用的是:

      radioGroup.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { group, checkedId ->
          //If not -1, means that is a radio button that was been clicked (don't know yet is checked or not)
          if (checkedId > 0) {
              //Get radio button element
              val radio: RadioButton = group.findViewById(checkedId)
      
              // Preguntar por si esta checked == true ?
              if (radio.isChecked) {
                  when (checkedId) {
                      R.id.rb_1 -> {
                          viewModel.onSetPv(1)
                      }
                      R.id.rb_2 -> {
                          viewModel.onSetPv(2)
                      }
                      else -> false
                  }
      
              }
          }
      
      })
      

      最好的问候!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-11
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多