Почему ArrayList всегда имеет одно и то же значение только в адаптере?

#java #android #date #datetime #arraylist

Вопрос:

Это худшая ошибка, которую я когда-либо видел.. Я получал журналы вызовов следующим образом.

 ArrayList<HashMap<String, String>> callLog= new ArrayList<>();
        HashMap<String, String> data = new HashMap<>();
        Cursor c = activity.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE   " DESC ");
        String phoneNumber,type,date,duration,name;

        while(c.moveToNext()){
            phoneNumber = c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));
            type = c.getString(c.getColumnIndex(CallLog.Calls.TYPE));
            date = c.getString(c.getColumnIndex(CallLog.Calls.DATE));
            duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));
            name = c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));

            data.put(Constants.PHONE_NUMBER, phoneNumber);
            data.put(Constants.NAME, name);
            data.put(Constants.DATE, date);
            data.put(Constants.TYPE, type);
            data.put(Constants.DURATION, duration);

            callLog.add(data);
        }
        c.close();
        return callLog;
 

Я пытался установить его на адаптер. Вот как я связал их с адаптером

 ContactViewAdapter contactViewAdapter = new ContactViewAdapter(getActivity(),getActivity(),CallLog(getActivity()),"contact");
        recyclerViewCallLog.setAdapter(contactViewAdapter);
 

Поскольку класс адаптера немного больше, поэтому я не добавляю весь контекст. Я просто добавляю конструктор здесь.

 public class ContactViewAdapter extends RecyclerView.Adapter<ContactViewAdapter.MyViewHolder> {

Context context;
    ArrayList<HashMap<String, String>> list;
    String type;
    Activity activity;

    public ContactViewAdapter(Activity activity,Context context, ArrayList<HashMap<String,String>> list,String type){
        this.activity = activity;
        this.context = context;
        this.list = list;
        this.type = type;
    }
 

Это понятно разработчику приложений для Android. Ошибка указана ниже :

  • На самом деле я использую несколько RecyclerView с помощью адаптера. Их компоновка практически одинакова, поэтому я решил использовать один адаптер, который мог бы уменьшить объем исходного кода. Это прекрасно работало для Контактов. Но ошибка доступна в журнале вызовов.
  • Метод может возвращать все журналы вызовов. В DialerFragment (где я вызываю этот метод) я также могу видеть весь журнал вызовов. Когда список попадает в адаптер, возвращается только один журнал вызовов.

Я удаляю номер телефона из списка Logcat.

[{дата=123123, имя=null, номер телефона= 4365643, продолжительность=45, тип=1}, {дата=43743, имя=null, номер телефона= 4543, продолжительность=45, тип=1}, {дата=23452, имя=null, номер телефона= 3245432, продолжительность=45, тип=1}, {дата=234523, имя=null, номер телефона= 3245432, продолжительность=45, тип=1}, {дата=1617550988892, имя=null, номер телефона= 2345, продолжительность=45, тип=1}, {дата=1617550923452388892, имя=null, номер телефона= 88018115723457032, продолжительность=45, тип=1}, {дата=16175502345988892, имя=null, номер телефона= 88018234511577032, продолжительность=45, тип=1}, {дата=16175509888234592, имя=null, номер телефона= 88018234511577032, продолжительность = 45, тип = 1}, {дата = 16175509888234592, имя = ноль, номер телефона = 88018112345577032, продолжительность=45, тип=1}, {дата=16172345550988892, имя=ноль, номер телефона= 88018112345577032, продолжительность=45, тип=1}, {дата=16175234550988892, имя=ноль, номер телефона= 88018234511571237032, продолжительность=45, тип=1}

Logcat — это из метода. Я также получаю один и тот же фрагмент входа в систему (активность) на странице. Logcat в адаптере.

 2021-09-19 14:00:07.995 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.012 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.026 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.040 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.054 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.068 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.082 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.098 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.112 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.126 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.140 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
2021-09-19 14:00:08.154 20558-20558/com.contact D/LOGCAT: {date=1617550988892, name=null, phoneNumber= 88018115747032, duration=45, type=1}
 

меня не волнует ДАТА. Они находятся в правильном формате. Они находятся в миллисекундах. меня тоже не волнует номер. Я добавил число (символ) в эти числа. Вот как я это назвал.

 @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        String phoneNumber = list.get(position).get(Constants.PHONE_NUMBER);
        String name = list.get(position).get(Constants.NAME);
        Bitmap imgBitmap = null;
        String photo = null;

        Log.d("LOGCAT", String.valueOf(list.get(position)));
}
 

Но почему они каждый раз возвращают одно и то же значение?

Комментарии:

1.Каждый индекс списка ссылается на то же HashMap самое, что вы просто переопределяете значение ключа с каждой итерацией цикла, теряя все ранее установленные значения. Переместите экземпляр data HashMap to внутрь цикла, и это должно решить проблему.

Ответ №1:

Вместо:

 ArrayList<HashMap<String, String>> callLog= new ArrayList<>();
    HashMap<String, String> data = new HashMap<>();
    Cursor c = activity.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE   " DESC ");
    String phoneNumber,type,date,duration,name;

    while(c.moveToNext()){
        phoneNumber = c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));
        type = c.getString(c.getColumnIndex(CallLog.Calls.TYPE));
        date = c.getString(c.getColumnIndex(CallLog.Calls.DATE));
        duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));
        name = c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));

        data.put(Constants.PHONE_NUMBER, phoneNumber);
        data.put(Constants.NAME, name);
        data.put(Constants.DATE, date);
        data.put(Constants.TYPE, type);
        data.put(Constants.DURATION, duration);

        callLog.add(data);
    }
    c.close();
    return callLog;
 

пробовать :

 ArrayList<HashMap<String, String>> callLog= new ArrayList<>();
    Cursor c = activity.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE   " DESC ");
    String phoneNumber,type,date,duration,name;

    while(c.moveToNext()){
        phoneNumber = c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));
        type = c.getString(c.getColumnIndex(CallLog.Calls.TYPE));
        date = c.getString(c.getColumnIndex(CallLog.Calls.DATE));
        duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));
        name = c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));

        HashMap<String, String> data = new HashMap<>();
        data.put(Constants.PHONE_NUMBER, phoneNumber);
        data.put(Constants.NAME, name);
        data.put(Constants.DATE, date);
        data.put(Constants.TYPE, type);
        data.put(Constants.DURATION, duration);

        callLog.add(data);
    }
    c.close();
    return callLog;
 

Комментарии:

1. Вы могли бы сократить код. И для других было бы полезно, если бы вы объяснили, что здесь происходит.

2. Здесь хэш-карта данных инициализации выполняется внутри цикла while для правильного кода