2016-08-13 103 views
0

我有一個listview項目包含幾個TextView s和7個自定義CheckBox es。在我的適配器類中,我有ArrayList存儲每個元素的所有數據,包括每個複選框狀態的布爾數組。帶有可點擊動畫複選框的Android listview元素

當我向下滾動列表時,我使用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'th元素應顯示是這樣的:

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

對於他們onCheckedChanged()的第5將被調用,這將觸發動畫。但正如我所說,我只想在點擊複選框時纔開始動畫。我打算使用另一個回調函數,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:我只是改變onCheckedChangedListeneronClickListener,希望它會幫助,但不知何故onClick()已經被調用,即使我只是滾動列表視圖,我不明白爲什麼發生這種情況。

回答

0

好吧,我明白了。每次繪製時我都會在自定義複選框類中開始動畫。