2013-02-22 1 views
12

У меня есть список, который может быть обновлен пользователем, но notifyDataSetChanged() не работает с адаптером, связанным с listView. Я использую его в фрагменте. Datbase обновляется, однако у adpater нет. Ниже моя реализация:ArrayAdapter.NotifyDataSetChanged() не работает?

My Main Fargment:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    myArrayList = new ArrayList<myList>(); 
    myArrayList = Database.getSharedObject(getActivity()).getMyList(); 
    if (myArrayList != null && myArrayList.size() > 0) { 
     adapter = new myListAdapter(getActivity(), 0, myArrayList); 
    } 

} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    View v = inflater.inflate(R.layout.mainfragment, container, false); 
    myListView = (ListView) v.findViewById(R.id.my_list_view); 
    myListView.setOnItemClickListener(this); 
    if (adapter != null) { 
     myListView.setAdapter(adapter); 
    } 

    return v; 
} 

После нескольких навигаций Список процесса обновляется и в моем onResume() методы я получаю обновленный список из базы данных и вызвать notifyDatasetChanged() метод, который не обновляется мой view, однако соответствующий массив из БД обновляется один.

@Override 
public void onResume() { 
    super.onResume(); 
    myArrayList = Database.getSharedObject(getActivity()).getMyList(); 
    adapter.setItems (myArrayList); 
    adapter.notifyDataSetChanged(); 

} 

MyListAdapter

public class MyListAdapter extends ArrayAdapter<Message> { 

    private ArrayList<Message> myList; 

    /* Context */ 
    private Context context; 

    public void setItems (ArrayList<Message> myList) { 
     this.myList = myList; 
    } 

    public MyListAdapter (Context context, int textViewResourceId, ArrayList<Message> myList) { 
     super(context, textViewResourceId, myList); 
     this.context = context; 
     this.myList = myList; 
    } 

    @Override 
    public View getView (int position, View v, ViewGroup parent) { 
     // Keeps reference to avoid future findViewById() 
     MyViewHolder viewHolder; 

     if (v == null) { 
      LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = li.inflate(R.layout.list_row, parent, false); 

      viewHolder = new MyViewHolder(); 
      viewHolder.txtImage = (ImageView) v.findViewById(R.id.message_icon); 
      viewHolder.txtMessage = (TextView) v.findViewById(R.id.message); 
      viewHolder.txtDate = (TextView) v.findViewById(R.id.date); 

      v.setTag(viewHolder); 
     } else { 
      viewHolder = (MyViewHolder) v.getTag(); 
     } 

     Message myMessage = new Message(); 
     myMessage = myList.get(position); 
     if (myMessage != null) { 
      viewHolder.txtMessage.setText(myMessage.getText()); 
      viewHolder.txtDate.setText(myMessage.getDate()); 
     } 
     return v; 
    } 

    static class MyViewHolder { 
     ImageView txtImage; 
     TextView txtMessage; 
     TextView txtDate; 
    } 
} 

Любая мысль о том, что происходит не так? Почему обновление списка не обновляется? Любые советы приветствуются.

+0

ли 'adapter.setItems' некоторый пользовательский метод вы сделали? – Sean

+0

@Sean да .. Это обычай метод. –

+0

сообщение myListAdapter – Blackbelt

ответ

26

notifyDataSetChanged() не будет работать для вас. Причины, почему

  1. Ваш адаптер теряет ссылку на ваш список.
  2. Всегда создавайте и добавляйте новый список в адаптер. Сделайте так: инициализируйте ArrayList, объявив глобально.

    ArrayList<myList> myArrayList=new ArrayList<myList>(); // как глобальная переменная

    Добавить список к адаптеру непосредственно проверить нулевое и пустое состояние. Установите адаптер в списке напрямую (не проверять для любого состояния)

    myListView.setAdapter(adapter);

  3. Добавление данных в myArrayList Каждый раз, когда (если ваши данные полностью новый, чем вы можете вызвать adapter.clear() и myArrayList.clear() перед фактическим добавлением данных в список), но не устанавливайте адаптер i.е Если новые данные заполняются в myArrayList, чем просто adapter.notifyDataSetChanged()

    adapter = new myListAdapter(getActivity(), 0, myArrayList); 
    
  4. Удалить эту строку

    adapter.setItems (myArrayList);

+0

Спасибо ... Это сработало для меня ... –

+0

Спасибо за предложение, его работа для меня !!! –

+0

Нехорошо всегда давать новый список вместо @ hovo888s решение работало –

-2

Если вы можете использовать notifyDataSetChanged(), но в Адаптере! создать маленький метод внутри

+0

Я создал уже подписи 'setItems (myArrayList)' –

0

Проблема заключается в конструкторе MyListAdapter

Вместо

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) { 
    super(context, textViewResourceId, scheduledMessageList); 
    this.context = context; 
    this.myList = myList; 
} 

попробовать

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) { 
    super(context, textViewResourceId, myList); 
    this.context = context; 
    this.myList = myList; 
} 

также вместо вас собственный метод setItems вы должны вызвать adapter.clear(); затем adapter.addAll(myArrayList);

4

Просто overrige метод GetCount

@Override 
    public int getCount() { 
     return myArrayList.count(); 
    } 
3

В вашем setItems метод пытается очистить старый ArrayList.

вместо этого:

public void setItems(ArrayList<Message> myList) { 
this.myList = myList; 
} 

Попробуйте это:

public void setItems(ArrayList<Message> myList) { 
this.myList.clear(); 
this.myList.addAll(myList); 
notifyDataSetChanged(); 
} 
+0

Спасибо за работу. –

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