具有可点击动画复选框的Android列表视图元素

时间:2016-08-13 09:35:45

标签: android listview checkbox

我有一个列表视图,其项目包含一些TextView和7个自定义CheckBox es。在我的适配器类中,我有ArrayList存储每个元素的所有数据,包括每个复选框状态的布尔数组。

当我向下滚动列表时,我使用convertView绘制新元素。例如,如果第一个项目消失,它的视图将用于绘制,比如说,第6个项目。我还使用ViewHolder存储对每个可见View项内所有ListView的引用。

现在,每个复选框都有onCheckedChangedListener,其内部的新状态被写入ArrayList的相应元素的布尔数组中。就像,我们更改了ListView的第2个元素的第4个复选框的状态,因此我们需要在ArrayList中找到2个元素,并在其布尔数组中更改第4个值

除了在ArrayList中更改布尔值之外,当我更改复选框的状态时,我也会启动动画,只有在我实际点击复选框时启动它才非常重要。但请记住我如何使用消失的项目来绘制新的项目?由于我正在重用convertView,我需要根据我想要绘制的元素的布尔数组来更改其复选框的状态。例如,我正在绘制ListView的第6个元素,并使用第一个元素的视图。比方说,第一个元素的复选框状态如下:

{true, true, true, true, true, false, false}

和第6个元素应该显示如下:

{false, false, false, false, false, false, false}

对于前5个onCheckedChanged()将被调用,这将触发动画。但正如我所说,我只想在物理上点击复选框时才开始制作动画。我打算使用另一个回调,onTouchEvent()会很棒,但它没有布尔参数来显示是否选中了复选框。任何想法都将受到强烈赞赏。

编辑1 - 我的适配器:

public class AlarmsArrayAdapter extends ArrayAdapter {

ArrayList<AlarmClock> alarmClockArrayList;
private Context context;

static class ViewHolder {
    TextView time;
    TextView songTitle;
    TextView nextRingTime;
    CheckBox repeatCheckBox;
    RelativeLayout repeatPanel;
    WeekDayCheckBox[] days = new WeekDayCheckBox[AlarmClock.DAYS_IN_WEEK];
}

public AlarmsArrayAdapter(Context context, ArrayList<AlarmClock> alarmClocks) {
    super(context, -1, alarmClocks);
    alarmClockArrayList = alarmClocks;
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     ViewHolder holder;
    AlarmClock alarmClock = alarmClockArrayList.get(position);
    Log.d("ADAP", "position = " + position);
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.alarm_clock_item, parent, false);

        holder = new ViewHolder();
        holder.time = (TextView) convertView.findViewById(R.id.alarmClockTime);
        holder.songTitle = (TextView) convertView.findViewById(R.id.alarmClockSong);
        holder.nextRingTime = (TextView) convertView.findViewById(R.id.nextRindDay);
        holder.repeatCheckBox = (CheckBox) convertView.findViewById(R.id.repeatCheckBox);

        holder.repeatPanel = (RelativeLayout) convertView.findViewById(R.id.repeatPanel);
        holder.days[0] = (WeekDayCheckBox) convertView.findViewById(R.id.MO);
        holder.days[1] = (WeekDayCheckBox) convertView.findViewById(R.id.TU);
        holder.days[2] = (WeekDayCheckBox) convertView.findViewById(R.id.WE);
        holder.days[3] = (WeekDayCheckBox) convertView.findViewById(R.id.TH);
        holder.days[4] = (WeekDayCheckBox) convertView.findViewById(R.id.FR);
        holder.days[5] = (WeekDayCheckBox) convertView.findViewById(R.id.SA);
        holder.days[6] = (WeekDayCheckBox) convertView.findViewById(R.id.SU);

        convertView.setTag(holder);
    } else
        holder = (ViewHolder) convertView.getTag();

    setListeners(holder, alarmClock);
    holder.time.setText(alarmClock.time);
    holder.songTitle.setText(alarmClock.songTitle);
    holder.nextRingTime.setText("No data");

    holder.repeatCheckBox.setChecked(alarmClock.weekPanelIsVisible);

    for (int i = 0; i < AlarmClock.DAYS_IN_WEEK; i++)
        holder.days[i].setChecked(alarmClock.weekDaysState[i]);
    return convertView;
}

private void setListeners(final ViewHolder holder, final AlarmClock alarmClock) {
    holder.songTitle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    });

    holder.time.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(context, TimePickerActivity.class);
            ((FragmentActivity) context).startActivityForResult(intent, MainActivity.TIME_PICK_REQUEST);
        }
    });

    holder.repeatCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (!isChecked) {
                holder.repeatPanel.setVisibility(View.GONE);
            } else {
                holder.repeatPanel.setVisibility(View.VISIBLE);
            }
            alarmClock.weekPanelIsVisible = isChecked;
        }
    });

    for (int i = 0; i < AlarmClock.DAYS_IN_WEEK; i++) {
        final int j = i;
        holder.days[j].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                holder.days[j].startAnimation();
                alarmClock.weekDaysState[j] = isChecked;
            }
        });
    }
}

}

AlarmClock的:

public class AlarmClock {
public static final int DAYS_IN_WEEK = 7;
public static int id = 0;

public String time;
public String songTitle;
boolean weekPanelIsVisible;
boolean [] weekDaysState;

public AlarmClock (String time, String title, boolean weekPanelVisibility, boolean [] weekDaysState) {
    id++;
    this.time = time;
    songTitle = title;
    weekPanelIsVisible = weekPanelVisibility;
    this.weekDaysState = new boolean[DAYS_IN_WEEK];
    this.weekDaysState = weekDaysState.clone();

}

编辑2:我刚刚将onCheckedChangedListener更改为onClickListener,希望它会有所帮助,但即使我只是滚动列表视图,我也会调用onClick(),我不明白为什么会这样。

1 个答案:

答案 0 :(得分:0)

好吧,我明白了。我每次画画时都会在我的自定义复选框类中启动动画。