Адаптер Android ListView с двумя ArrayList

В нашем чат-приложении мы хотим использовать классную новую библиотеку SQLBrite для обновления чата об изменениях в базе данных. Так как наш чат имеет бесконечную прокрутку, а в чате может быть очень большой список сообщений, мы хотим разделить ArrayList, поставляемый адаптеру Chat ListView, на два списка. Проверьте графику для идеи. введите здесь описание изображения

  1. Мы хотим установить точку в базе данных, выше которой старые сообщения будут запрашиваться обычными запросами SQLite. И ниже этой точки мы хотим установить SQLBrite, который принесет нам свежие сообщения, добавленные в базу данных.
  2. Каждая часть должна заполнить свой соответствующий ArrayList. И два массиваList должны быть объединены в одном адаптере.

Мой вопрос возможно ли это сделать? Если да, то как мы можем объединить и обрабатывать два динамических списка ArrayList в одном адаптере?

Редактировать 1 1. Мне нужно сохранить позицию прокрутки чата во время сброса и не мерцать во время обновления ArrayLists.


person Rafael    schedule 22.04.2015    source источник
comment
Adopter примет только один массив, вам нужно объединить оба массива. Вам нужно найти решение для динамического обновления списков и повторного слияния   -  person    schedule 22.04.2015
comment
почему бы не использовать MergeCursor?   -  person pskink    schedule 22.04.2015


Ответы (4)


1. С помощью дженериков вы можете обрабатывать два массива с одним ArrayList.

Например в адаптере:

setListData(ArrayList<T> pListData)
{
    mListData=pListData;
}

С учетом

 getView(int position, View convertView, ViewGroup parent){

      T commonModel= getItem(position);
    if(T instanceof ArrayListOneModel){
     ArrayListOneModel model1=(ArrayListOneModel)T;
    do stuf for first arraylit...
      }
 }
  1. Если вы используете одну и ту же модель, вы можете установить тип (enum) как для arraylist, так и во время показа, вы можете это проверить.

3. В противном случае вы можете сначала добавить старые данные в arraylist, а затем с помощью коллекции addAll() добавить в нее второй список последних сообщений. тогда

  adapter.notifyDataSetChanged() 

установит первое старое сообщение, затем установит последнее сообщение в вашем списке

Дополнительные разъяснения: во втором подходе, если у вас есть разные модели для обоих массивов, тогда добавьте перечисление в обе модели в качестве установщика-получателя.

  public enum eType{
   FIRST_LIST_TYPE,SECOND_LIST_TYPE
   }

Во время выборки данных из разных БД задайте тип модели. например

  public class model{
   private enum eType;

// другой сеттер-геттер из вашей БД /** * Сеттер-геттер: */

   public void seteType(enum eType)
     {
      this.eType = eType; 
     }
    public enum geteType()
   {
       return eType;
    }

  }

Во время выборки набора данных Тип, например.

 Model model = new Model();
 model.seteType(eType.FIRST_LIST_TYPE) ;
  //same for 2nd db.
 & simply check type inside getView() according to your requirement.
person Deepanker Chaudhary    schedule 22.04.2015
comment
@Deepanker Не могли бы вы немного рассказать о втором решении с фрагментом кода? - person Praveen; 02.09.2016
comment
@Praveen Я добавил больше пояснений для второго подхода. Но лучше всего использовать третий подход, нет необходимости проверять какой-либо тип, только addAll добавит все данные. - person Deepanker Chaudhary; 02.09.2016
comment
Спасибо @DeepankerChaudhary. Я использовал метод добавления всех ранее. В настоящее время я использую второй подход, используя логическое значение для различения типов списка, но таким образом приложение не будет масштабироваться, если будет больше типов списка. Поэтому хотел изучить способы использования enum, отличные от использования дженериков. - person Praveen; 06.09.2016

yes that is possible inside BaseAdapter getCount method write following code

 @Override
public int getItemCount() {
    return list1.size()+list2.size();
}

и внутри метода getView вы можете сделать что-то вроде ниже

 public View getView(int position, View convertView, ViewGroup viewGroup) {
       if(position < list1.size) {
            Object object = list1.get(position);
            //write code to inflate view here related to list 1

       }
       else {
          Object object = list2.get(position - list1.size());
          //write code to inflate raw here related to list 2
       } 
 }
person amodkanthe    schedule 22.04.2015

Вы можете передать только один список в Adapter, что означает, что вам нужно объединить оба массива. Чтобы объединить оба массива. они должны быть одного типа, то есть массив одного и того же пользовательского объекта.

Если массивы обновляются динамически, то снова объединяйте массивы по мере изменения их данных и каждый раз вызывайте notifyDataSetChanged(), чтобы отразить изменения в списке.

person Community    schedule 22.04.2015

Да, ты можешь сделать это. но оба массива должны иметь общий формат данных. например, .. В адаптере вы можете сделать такой метод, как

public void addMessages( <your_array_list> data ) {
    list.addAll(data); //where list is your data container
}

теперь у вас может быть два массива, например

ArrayList<your_type> oldMsg;
ArrayList<your_type> newMsg;
..
..
...
.
.

поэтому вы можете вызвать метод адаптера, который мы создали

yourAdapter.addMessages(oldMsg);
yourAdapter.addMessages(newMsg);
person Moinkhan    schedule 22.04.2015
comment
не забудьте написать notifyDataSetChanged() - person Moinkhan; 22.04.2015