2014-09-10 39 views
0

我有一個ListView,每個ListView項有一個Switch小部件,我遇到的問題是當我在ArrayAdapter中設置值setOnCheckedChangeListener get觸發時。如何在不觸發setOnCheckedChangeListener的情況下在適配器中設置值?我發現了另一個類似的問題here,但這不適用於我。以下是我的ArrayAdapter代碼。開關小部件 - onCheckedChanged在ArrayAdapter中設置值時觸發

public class AlarmsAdapter extends ArrayAdapter<Alarms> { 

private List<Alarms> alarmsList; 
private Context context; 

private ContactDetailsFragment cdFragment; 

public AlarmsAdapter(Context context, int textViewResourceId, List<Alarms> alarms) { 
    super(context, textViewResourceId, objects); 
    this.context=context; 
    alarmsList=alarms; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    final Alarms alarm = alarmsList.get(position); 

    View view = convertView; 
    ViewHolder holder = null; 

    if(view == null) { 
     LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = vi.inflate(R.layout.alarm_row, null); 

     holder = new ViewHolder(); 
     holder.alarmLabel = (TextView) view.findViewById(R.id.alarmLabel); 
     holder.alarmDate = (TextView) view.findViewById(R.id.alarmDate); 
     holder.alarmTime = (TextView) view.findViewById(R.id.alarmTime); 
     holder.alarmEnabled = (Switch) view.findViewById(R.id.alarmEnabled); 

     view.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder) view.getTag(); 
    } 

    if(alarm != null) { 
     int alarmId = alarm.getAlarmDay(); 
     holder.alarmLabel.setText(String.valueOf(alarmId)); 

     // Alarm Date Time 
     long mDateTime = alarm.getAlarmTime(); 
     Date nDate = new Date(mDateTime); 

     DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy"); 
     DateFormat timeFormat = new SimpleDateFormat("hh:mm a"); 

     holder.alarmDate.setText(dateFormat.format(nDate)); 
     holder.alarmTime.setText(timeFormat.format(nDate)); 
     holder.alarmEnabled.setChecked((alarm.getIsOn() == 1) ? true : false); 
     holder.alarmEnabled.setTag(alarm.get_uid()); 

     holder.alarmEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       alarm.setIsOn((isChecked) ? 1:0); 
       cdFragment.addCanceledAlarm(alarm); 
      } 
     }); 
    } 
    return view; 
} 

class ViewHolder { 
    TextView alarmLabel; 
    TextView alarmDate; 
    TextView alarmTime; 
    Switch alarmEnabled; 
} 

public void setCdFragment(ContactDetailsFragment cdFragment) { 
    this.cdFragment = cdFragment; 
} 

}

回答

2

有幾種方法,你如何能應對這樣的局面。

首先和最簡單的方法是在您從代碼中調用setChecked之前每次刪除OnCheckedChangeListener

holder.alarmTime.setText(timeFormat.format(nDate)); 

// Here we remove the listener, so it won't be triggered 
holder.alarmEnabled.setOnCheckedChangeListener(null); 

holder.alarmEnabled.setChecked(alarm.getIsOn() == 1); 
holder.alarmEnabled.setTag(alarm.get_uid()); 
holder.alarmEnabled.setOnCheckedChangeListener(... 

第二種方式是一些代碼添加到您的OnCheckedChangeListener您的驗證,如果新狀態是從開關的當前狀態不同。代碼示例:

holder.alarmEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
     if (alarm.getIsOn() != (isChecked ? 1 : 0)) { 
      // This code is executed only if new state 
      // of a switch is different from current state 
      alarm.setIsOn((isChecked) ? 1 : 0); 
      cdFragment.addCanceledAlarm(alarm); 
     } 
    } 
}); 

第三種方法是引入某種標誌,表示開關狀態是由用戶還是從代碼改變的。因此,在您的聽衆中,您可以在代碼中明確呼叫setChecked時忽略這些情況。

+0

謝謝@vasart,我使用了第一個選項,它解決了我的問題。 – Byron 2014-09-11 15:09:16

相關問題