2015-05-20 3 views
0

Я работаю с сигнализацией. У меня есть вся система сигнализации (модели, БД, служба, приемник и т. Д.), Но это не относится к делу.Проблема с ListView, где каждый элемент отображает ArrayList модели

Я группирую каждый сигнал тревоги в arraylist под названием «matchingAlarms» на основе их повторяющихся дней (воскресенье-суббота), который основан на входе пользователей. я получил эту часть вниз, никакой проблемы

Теперь с этим matchingAlarms Arraylist Я пытаюсь сделать ListView, где каждый элемент в этом ListView показывает название сигнала и сигнал тревоги Время для каждого индекса этого ArrayList (я хочу их для изменения в ListView с таймером).

Пример:

У меня есть 1 сигнал: 8 AM - 11 П.М., Повторяющиеся дни: вс-чт И 1 сигнал 9 AM - 12 П.М., Повторяющиеся дни: пт-сб

Каждый из этих сигналов тревоги в индексе matchingAlarms Arraylist, поэтому размер matchingAlarms равен 2.

Я думаю, что я упомянул все, теперь для кода.

AlarmListAdapter:

public class AlarmListAdapter extends BaseAdapter { 

public static Context mContext; 
private List<AlarmModel> mAlarms; 
private ArrayList<ArrayList<AlarmModel>> mMatchingAlarms = new ArrayList<ArrayList<AlarmModel>>(); 
private ArrayList<AlarmModel> grouped = new ArrayList<AlarmModel>(); 

private Animation anim; 

AlarmModel model; 
TextView txtTime,txtName,sun,mon,tue,wed,thur,fri,sat; 
ToggleButton btnToggle; 
int matchingAlarmsIndex = 0; 
int groupIndex = 0; 
int itemIndex; 

public AlarmListAdapter(Context context, List<AlarmModel> alarms, ArrayList<ArrayList<AlarmModel>> matchingAlarms) { 
    mContext = context; 
    mAlarms = alarms; 
    mMatchingAlarms = matchingAlarms; 
    anim = AnimationUtils.loadAnimation(mContext, R.anim.right_left); 
} 

public AlarmListAdapter(Context context) { 
    mContext = context; 
} 

public void setAlarms(List<AlarmModel> alarms) { 
    mAlarms = alarms; 
} 

@Override 
public int getCount() { 
    if (mMatchingAlarms != null) { 
     return mMatchingAlarms.size(); 
    } 
    return 0; 
} 

@Override 
public ArrayList<AlarmModel> getItem(int position) { 
    if (mMatchingAlarms != null) { 
     return mMatchingAlarms.get(position); 
    } 
    return null; 
} 

@Override 
public long getItemId(int position) { 
    if (mAlarms != null) { 
     return mAlarms.get(position).id; 
    } 
    return 0; 
} 



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

    if (view == null) { 
     LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(R.layout.alarm_list_item, parent, false); 
    } 

    txtName = (TextView) view.findViewById(R.id.alarm_item_name); 
    txtTime = (TextView) view.findViewById(R.id.alarm_item_time); 
    sun = (TextView) view.findViewById(R.id.alarm_item_sunday); 
    mon = (TextView) view.findViewById(R.id.alarm_item_monday); 
    tue = (TextView) view.findViewById(R.id.alarm_item_tuesday); 
    wed = (TextView) view.findViewById(R.id.alarm_item_wednesday); 
    thur = (TextView) view.findViewById(R.id.alarm_item_thursday); 
    fri = (TextView) view.findViewById(R.id.alarm_item_friday); 
    sat = (TextView) view.findViewById(R.id.alarm_item_saturday); 
    btnToggle = (ToggleButton) view.findViewById(R.id.alarm_item_toggle); 

    grouped = getItem(position); 


    Timer timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      ((AlarmListActivity) mContext).runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        if ((groupIndex + 1) <= grouped.size()) { 
         model = grouped.get(groupIndex); 
         updateTimeAndDates(model); 
         groupIndex++; 
        } 
        if ((groupIndex + 1) > grouped.size()) { 
         groupIndex = 0; 
        } 
        Log.i("", String.valueOf(groupIndex)); 
       } 
      }); 

     } 
    }, 0, 2500); 



    return view; 
} 

private void updateTextColor(TextView view, boolean isOn) { 
    if (isOn) { 
     view.setTextColor(Colors.IndianRed); 
    } else { 
     view.setTextColor(Color.LTGRAY); 
    } 
} 

private void updateTimeAndDates(AlarmModel model) { 
    txtName.setText(model.name); 
    txtName.startAnimation(anim); 
    txtTime.setText(DietDoctor.to12Hours(model.timeHour, model.timeMinute)); 
    txtTime.startAnimation(anim); 

    updateTextColor(sun, model.getRepeatingDay(AlarmModel.SUNDAY)); 
    updateTextColor(mon, model.getRepeatingDay(AlarmModel.MONDAY)); 
    updateTextColor(tue, model.getRepeatingDay(AlarmModel.TUESDAY)); 
    updateTextColor(wed, model.getRepeatingDay(AlarmModel.WEDNESDAY)); 
    updateTextColor(thur, model.getRepeatingDay(AlarmModel.THURSDAY)); 
    updateTextColor(fri, model.getRepeatingDay(AlarmModel.FRDIAY)); 
    updateTextColor(sat, model.getRepeatingDay(AlarmModel.SATURDAY)); 

    btnToggle.setChecked(model.isEnabled); 
} 

} 

AlarmListActivity:

public class AlarmListActivity extends ListActivity { 

    private AlarmListAdapter mAdapter; 
    private AlarmDBHelper dbHelper = new AlarmDBHelper(this); 
    private Context mContext; 
    private boolean fromSettings; 
    private ArrayList<ArrayList<AlarmModel>> matchingAlarms = new ArrayList<ArrayList<AlarmModel>>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if(getIntent().hasExtra("FromSettings")) 
     fromSettings = getIntent().getExtras().getBoolean("FromSettings"); 

     mContext = this; 

     requestWindowFeature(Window.FEATURE_ACTION_BAR); 

     setContentView(R.layout.activity_alarmlist); 

     setGroups(); 

     mAdapter = new AlarmListAdapter(this, dbHelper.getAlarms(), matchingAlarms); 

     setListAdapter(mAdapter); 
    } 
... 

public void setGroups() { 
     ArrayList<AlarmModel> group = new ArrayList<AlarmModel>(); 
     List<AlarmModel> mAlarms = dbHelper.getAlarms(); 
     for (int i = 0; i < mAlarms.size(); i++) { 
      if ((i + 1) != mAlarms.size()) { 
       boolean result = Arrays.equals(mAlarms.get(i).getRepeatingDays(), mAlarms.get(i + 1).getRepeatingDays()); 
       Log.i("Result", Boolean.toString(result)); 
       if (result) { 
        if (i == 0)group.add(mAlarms.get(i)); 
        group.add(mAlarms.get(i+1)); 
       } 
       if (!result) { 
        if (i == 0)group.add(mAlarms.get(i)); 
        matchingAlarms.add(group); 
        group = new ArrayList<AlarmModel>(); 
        group.add(mAlarms.get(i+1)); 
       } 
      } 

      if ((i + 1) == mAlarms.size()) { 
       boolean result1 = Arrays.equals(mAlarms.get(i).getRepeatingDays(), mAlarms.get(i - 1).getRepeatingDays()); 
       Log.i("Result_1", Boolean.toString(result1)); 
       if (result1) { 
        group.add(mAlarms.get(i)); 
        matchingAlarms.add(group); 
       } 
       if (!result1) { 
        matchingAlarms.add(group); 
        group = new ArrayList<AlarmModel>(); 
        group.add(mAlarms.get(i)); 
       } 
      } 

     } 
     Log.i("Matching Alarms", String.valueOf(matchingAlarms.size())); 
     Log.i("Group", String.valueOf(matchingAlarms.get(0).size())); 
     Log.i("UnGrouped", String.valueOf(mAlarms.size())); 

    } 

Я думаю, что реальная проблема заключается в GetView метода и таймера внутри него. Как вы можете видеть на картинке ниже, я только получил Fri-Sat. Первый пункт должен иметь тревоги с повторяющимися днями: Вс-чт

enter image description here

ответ

0

, что происходит, потому что getView становится называются несколько раз (по крайней мере один раз для каждого пункта на ListView).

Итак, на вашем адаптере, когда вы используете все эти поля TextView, вы каждый раз переписываете их ссылку, и только последний действительно правильный.

Чтобы исправить это, лучше всего применить шаблон Holder. Если вы Google для этого, вы найдете около миллиона и пятьсот тысяч примеров этого и как это работает.

private static class Holder { 
    AlarmModel model; 
    TextView txtTime,txtName,sun,mon,tue,wed,thur,fri,sat; 
    ToggleButton btnToggle; 
    Timer timer = new Timer(); 
} 

, а затем обновить ваш updateTimeAndDates быть:

updateTimeAndDates(Holder h) { 
    h.timer.cancel(); 
    h.timer.purge(); 
    // carry on updating the values and create the re-schedule the updates. 
} 

также я хотел бы предложить на таймере и просто использовать .postDealayed(Runnable, long); на представлении. Таймеры вообще не очень хороши.

Смежные вопросы