ListView не заполнен. Проблема с ViewPager и фрагментами - PullRequest
0 голосов
/ 05 января 2019

У меня три фрагмента, переключенных с помощью ViewPager, а третий содержит ListView.

Моя проблема в том, что ListView не заполняется при первом переключении на этот фрагмент. Я должен переключиться обратно к первому, затем снова к третьему, и только ListView будет заполнен. В чем здесь проблема?

Как работает ViewPager?

Вот мой TabAdapter

public class TabAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

TabAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    return mFragmentList.get(position);
}

public void addFragment(Fragment fragment, String title) {
    mFragmentList.add(fragment);
    mFragmentTitleList.add(title);
}

@Nullable
@Override
public CharSequence getPageTitle(int position) {
    return mFragmentTitleList.get(position);
}

@Override
public int getCount() {
    return mFragmentList.size();
}

}

Вот ListAdapter для listView

   public class ListAdapter extends BaseAdapter {
    private ArrayList data = new ArrayList();

    public ListAdapter(LinkedHashMap<String, ArrayList<String>> lhm) {
        try {
            data.addAll(lhm.entrySet());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public LinkedHashMap.Entry<String, ArrayList<String>> getItem(int position) {
        return (LinkedHashMap.Entry) data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }
    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        final LinkedHashMap.Entry<String, ArrayList<String>> item = getItem(position);
        final ArrayList quotesList = item.getValue();
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.archive_list, parent, false);
        }
        TableRow tableRow = convertView.findViewById(R.id.container);
        TextView title = convertView.findViewById(R.id.title);
        ImageView copy = convertView.findViewById(R.id.copy);
        copy.setVisibility(View.INVISIBLE);
        title.setText(item.getKey() + " Quotes");

        tableRow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), ViewActivity.class);
                intent.putExtra("title", item.getKey());
                intent.putStringArrayListExtra("quotes", quotesList);
                if (interstitialAd.isLoaded()) {
                    interstitialAd.show();
                    startActivity(intent);
                } else {
                    startActivity(intent);
                }
            }
        });
        return convertView;
    }
}

Обновление

Проблема, кажется, из Linkedhashmap. Я попытался вручную поместить значения в Hashmap, и это сработало. Проблема сейчас в моем текущем коде. Я заполняю свой hashmap, получая данные из firebase, и это кажется проблемой? Возможно, он не заполняется так быстро?

    private void initArchives() {
    DatabaseReference dBase = FirebaseDatabase.getInstance().getReference().child("archive");
    dBase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
                DataPojo dp = snapshot.getValue(DataPojo.class);
                hm.put(dp.getName(), dp.getMessages());
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_archive, container, false);
    listView = view.findViewById(R.id.listView);
    searchView = view.findViewById(R.id.searchView);


    initArchives();
    listAdapter = new ListAdapter(hm);
    listView.setAdapter(listAdapter);
    listView.invalidateViews();

    loadAds();

    return view;
}

1 Ответ

0 голосов
/ 05 января 2019

Прежде всего FragmentStatePagerAdapter действительно боль в заднице. Но мы должны работать с этим. Я предлагаю вам Ctrl + клик по FragmentStatePagerAdapter и прочитать исходный код.

Другое дело, что добавление фрагментов в ваш ArrayList с помощью метода addFragment() может быть не лучшей идеей, поскольку FragmentStatePagerAdapter сохраняет состояния фрагментов и загружает их из своих FragmentManager.

Таким образом, добавленный вами фрагмент может не совпадать с полученным вами. Возможным решением этого было бы использование тегов.

Некоторые должны прочитать статьи на эту тему здесь здесь и здесь .

И еще одна вещь. ViewPager создает три фрагмента за раз при использовании FragmentStatePagerAdapter. Сначала он создает фрагмент для отображения, а затем фрагмент справа и последний фрагмент слева. Поскольку у вас есть три фрагмента, последний (третий) фрагмент не создается сразу (слева от первого фрагмента нет фрагмента). Может быть, вы загружаете какие-то данные, для загрузки которых требуется третий фрагмент? И в следующий раз при отображении 3-го фрагмента он загружается из сохраненного состояния FragmentStatePagerAdapter. Это всего лишь несколько возможностей для размышления. Не обязательно это правильное решение. Удачи.

...