Android:在ListView适配器

时间:2016-11-08 07:43:34

标签: android listview listener oncheckedchanged

我的应用中有一个listView。对于listView中的每个元素,它都有一个Switch。以前我在listView Adapter的getView方法中为Switch实现了一个onClickListener。但是,我发现尽管用户点击交换机时它确实有效,但当用户在Switch上滑动时它不起作用。然后我尝试将onClickListener更改为onCheckedChangeListener。当用户在Switch上单击或滑动时它可以工作,但是,当我滚动listView以便元素消失时,我发现最初检查的Switch变为未选中状态。

你可以帮忙吗?下面是我在listView Adapter中的getView方法的代码:

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    class viewHolder {
        public TextView tvSceneName;
        public Switch swSelectSwitch;
    }
    final viewHolder holder;

    final View v = convertView;

    // Use ViewHolder to avoid findViewById each time the user scroll
    if (convertView == null) {
        holder = new viewHolder();
        convertView = mInflater.inflate(R.layout.scene_list_element, parent, false);
        holder.tvSceneName = (TextView) convertView.findViewById(R.id.tvSceneName);
        holder.swSelectSwitch = (Switch) convertView.findViewById(R.id.swScene);
        convertView.setTag(holder);
    } else {
        holder = (viewHolder) convertView.getTag();
    }


    if(holder.swSelectSwitch != null) {

        // Set the switch to correct on/off status
        holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn());

        // Set up On checked change listener for the switch
        holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {

                // Set the new status to arraylist
                Switch sw = (Switch) v.findViewById(R.id.swScene);
                MainActivity.sceneArrayList.get(position).set_isOn(sw.isChecked());

        });
    }
}

修改 在进一步测试中,我发现我新添加的onCheckChangedListener中存在错误(因为我从onClickListener复制了一些代码)。另外我找到了一个解决方案,它是在我按代码设置Switch之前将onCheckChangedListener设置为null。

if(holder.swSelectSwitch != null) {

    // Set the switch to correct on/off status
    holder.swSelectSwitch.setOnCheckedChangeListener(null);
    holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn());

    // Set up On checked change listener for the switch
    holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {

            // Set the new status to arraylist
            mDataSource.get(position).set_isOn(isChecked);

    });
}

2 个答案:

答案 0 :(得分:1)

ViewHolder模式的要点是View s正在被回收。

您从mDataSource获取已检查状态,但未对其进行更新,因此当View被回收时,Switch将返回其原始(未选中)状态。< / p>

发生更改时,您应该更新mDataSource中的状态:

@Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {

    // Set the new status to arraylist
    MainActivity.sceneArrayList.get(position).set_isOn(isChecked);

    // updating mDataSource
    mDataSource.get(position).set_isOn(isChecked);
}

答案 1 :(得分:0)

您应该删除第if(holder.swSelectSwitch != null) {行: 滚动时,视图不会被销毁但会被回收,因此在滚动后调用getView时,convertView不为空。当convertView不为空时,您将重新使用已创建的持有者并将其放入视图标记中。