Представление содержимого ListFragment еще не создано после отсоединения прикрепления

Я новичок в программировании для Android. Я попробовал заполнить ListFragment из базы данных, и он работает хорошо.
Я мог отображать значения, но когда я пытался обновить представление, отсоединяя и снова присоединяя фрагмент, получалось представление содержимого ошибки, еще не созданное в getListView(), которое я включите onActivityCreated.
Есть идеи?

public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  listView = getListView();

  db = new DatabaseAccess(getActivity().getApplicationContext());
  List<Contact> contacts = db.getAllContacts();

  if (contacts.size() > 0) {
    List<Map<String, String>> contactList = new ArrayList<Map<String, String>>();
    for (Contact con : contacts) {
      Map<String, String> data = new HashMap<String, String>(2);
      data.put("name", con.getName());
      data.put("number", con.getNumber());
      contactList.add(data);
    }
    SimpleAdapter adapter = new SimpleAdapter(getView().getContext(), contactList, android.R.layout.simple_list_item_2, new String[] {"name", "number"}, new int[] {android.R.id.text1, android.R.id.text2});

    listView.setAdapter(adapter);
  } else {
    setEmptyText("Masih belum ada kontak");
  }
  setListShown(true);
  db.closeDB();
}

когда я пытаюсь обновить фрагмент

void refreshFragment() {
  Fragment frg = getFragmentManager().findFragmentById(R.id.fragment);
  FragmentTransaction fragTransaction = this.getFragmentManager().beginTransaction();
  fragTransaction.detach(frg);
  fragTransaction.attach(frg);
  fragTransaction.commit();
}

person saintfalcon    schedule 18.01.2016    source источник
comment
Да, не обновляйте фрагмент с помощью команды "Отсоединить, прикрепить". Выполните findFragment, проверьте, является ли фрагмент правильным экземпляром, и вызовите функцию обновления, которая просто обновит содержимое.   -  person Raanan    schedule 18.01.2016
comment
@Raanan: спасибо, но, пожалуйста, объясните, как проверить, является ли фрагмент правильным экземпляром, как это сделать?   -  person saintfalcon    schedule 18.01.2016
comment
if(fragment instanceof MyFragment) {... }, прежде чем вы приведете его к MyFragment, именно так, как вы это сделали.   -  person Raanan    schedule 18.01.2016


Ответы (2)


Обобщить:

  1. Присоединение/отсоединение не является правильным способом обновления представления.
  2. найдите фрагмент и вызовите функцию обновления, чтобы обновить содержимое
  3. setListShow - не нужно вызывать, список по умолчанию невидим, пока не будет сделан вызов setAdapter - тогда, если есть контент, он станет видимым.
  4. Вызовите setListAdapter также, если адаптер пуст.

Чтобы обновить список, вам не нужно создавать все заново, просто обновите содержимое адаптера и вызовите функцию invalidateDataSet.

person Raanan    schedule 18.01.2016

Наконец-то получилось что-то правильное (я думаю), основанное на предложении @Raanan, которое создает функцию для заполнения списка и может быть вызвана при необходимости.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  listView = getListView();
  populateList(listView);
}

void populateList(ListView lv) {
  db = new DatabaseAccess(getActivity().getApplicationContext());
  List<Contact> contacts = db.getAllContacts();

  if (contacts.size() > 0) {
    List<Map<String, String>> contactList = new ArrayList<Map<String, String>>();
    for (Contact con : contacts) {
      Map<String, String> data = new HashMap<String, String>(2);
      data.put("name", con.getName());
      data.put("number", con.getNumber());
      contactList.add(data);
    }
    SimpleAdapter adapter = new SimpleAdapter(getView().getContext(), contactList, android.R.layout.simple_list_item_2, new String[] {"name", "number"}, new int[] {android.R.id.text1, android.R.id.text2});

    lv.setAdapter(adapter);
  } else {
    setEmptyText("Masih belum ada kontak");
  }
  setListShown(true);
  db.closeDB();
}

и метод обновления

void refreshFragment() {
  Fragment frg = getFragmentManager().findFragmentById(R.id.fragment);
  if (frg instanceof ScreenContact) {
    ((ScreenContact) frg).populateList(((ScreenContact) frg).getListView());
  }
}

ScreenContact — это мой класс фрагментов, производный от ListFragment. но все же, когда данные пусты, я все еще не могу показать «setEmptyText», как при первом запуске приложения.

person saintfalcon    schedule 18.01.2016
comment
это потому, что вы вызываете setListShown(true); вне если. - person Raanan; 18.01.2016
comment
developer.android.com/reference/android/app/ — приложениям обычно не нужно использовать это самостоятельно. - person Raanan; 18.01.2016
comment
если я не использую этот setListShown(true), анимация прогресса продолжает вращаться и не показывает пустой текст или данные (если они доступны) - person saintfalcon; 18.01.2016
comment
Я создал ответ. - person Raanan; 18.01.2016