Фрагмент Android GetItem вызывается дважды, из-за чего данные не отображаются?

#java #android #android-fragments

#java #Android #android-фрагменты

Вопрос:

У меня эта проблема с моим Android Fragment . Происходит то, что у меня есть несколько Fragment s в моем TabLayout . Я создаю их без проблем, но я сталкиваюсь с проблемой, когда при первом создании экземпляра Fragment создается фрагмент, и данные, похоже, изначально загружены правильно. Однако после того, как все данные загружены изначально, выполняется второй вызов для создания экземпляра, Fragment потому что Fragment getItem(int position) по какой-то причине метод вызывается еще раз. Однако, поскольку я инициализирую данные только в первый раз (в моем фрагменте есть static переменная, которую я создал, которая инициализирует данные для меня), static переменная уже будет знать, что данные уже загружены правильно и что она не должна загружать данные снова. В результате мой экран загрузки, похоже, отображается непрерывно, потому что данные во второй раз не могут быть извлечены. Есть ли какой-либо способ обойти это? Либо фрагмент создается только один раз, либо загружаются данные только во второй и последний раз, когда Fragment создается? Вот мой код:

 private void setupTabLayout() {
    View layout = findViewById(R.id.activity_main);
    if (layout != null) {
        tabLayout = (TabLayout) layout.findViewById(R.id.tab_layout);
    }
    tabLayout.addTab(tabLayout.newTab().setText("First Fragment"));
    tabLayout.addTab(tabLayout.newTab().setText("Second Fragment"));
    tabLayout.addTab(tabLayout.newTab().setText("Third Fragment"));
    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    if(viewPager != null) {
        viewPager.setOffscreenPageLimit(3);
        final PagerAdapter adapter = new PagerAdapter
                (getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }
}
  

PagerAdapter.java

 public class PagerAdapter extends FragmentStatePagerAdapter{
    int numTabs;

    public PagerAdapter(FragmentManager fm, int numTabs) {
        super(fm);
        this.numTabs = numTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                //Here, the PublicTabFragment is instantiated twice,
                //causing the onResume and onCreate methods of my PublicTabFragment() 
                //to be called twice.
                PublicTabFragment tab1 = new PublicTabFragment();
                return tab1;
            case 1:
                FollowersTabFragment tab2 = new FollowersTabFragment();
                return tab2;
            case 2:
                ProfileTabFragment tab3 = new ProfileTabFragment();
                return tab3;
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return numTabs;
    }
  

PublicTabFragment:

 private View fragmentView;
private View progressOverlay;
//Declared static so I don't have to call getPublicPostsFromDatabase twice
private static LocationService locationService;
private static Location currentLocation;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (fragmentView == null) {
        fragmentView = inflater.inflate(R.layout.posts_tab, container, false);
    }
    return fragmentView;
}

@Override
public void onResume() {
    super.onResume();
    setupLocation();
}

private void setupLocation() {
    Context context = getContext();
    //Checked once staticly so I don't have to call getPublicPostsFromDatabase twice
    if(locationService == null) {
        locationService = new LocationService(context, new LocationUpdateListener() {
            @Override
            public void canReceiveLocationUpdates() {

            }

            @Override
            public void cannotReceiveLocationUpdates() {
                //well we know we cant receive updates so we have to create a settings request
            }

            //update location to our servers for tracking purpose
            @Override
            public void updateLocation(Location location) {
                if (location != null) {
                    currentLocation = location;
                    progressOverlay = fragmentView.findViewById(R.id.progress_overlay);
                    progressOverlay.setVisibility(View.VISIBLE);
                    swipeContainer = (SwipeRefreshLayout) fragmentView.findViewById(R.id.swipeContainer);
                    swipeContainer.setColorSchemeResources(R.color.colorPrimary);
                    databaseQuery.getPublicPostsFromDatabase(currentLocation, progressOverlay, fragmentView, getContext(), R.id.public_posts_feed);
                }
            }

            @Override
            public void updateLocationName(String localityName, Location location) {
                locationService.stopLocationUpdates();
            }
        });
        locationService.startUpdates();
    }
}
  

РЕДАКТИРОВАТЬ: я попытался установить для locationService переменной значение НЕ static, и вызов getPublicPostsFromDatabase работает нормально во второй раз, когда создается экземпляр фрагмента, но затем проблема заключается в том, что getPublicPostsFromDatabase метод вызывается дважды. Даже если я установлю, что a static boolean variable находится true внутри getPublicPostsFromDatabase и вызывается getPublicPostsFromDatabase только тогда, когда static boolean variable есть false , Fragment экземпляр создается во второй раз только после getPublicPostsFromDatabase завершения, которое затем будет getPublicPostsFromDatabase вызвано снова.

Ответ №1:

Вы пробовали с логическим значением?

 private Boolean mLoad = false;
  

и когда они загружаются, установите для него значение true, а для загрузки установите это условие

 if (!mLoad) {
    ...
    mLoad = true;
}
  

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

1. Я пробовал использовать логическое значение, но проблема, похоже, в том, что getPublicPostsFromDatabase оно завершается до создания экземпляра Fragment во второй раз. В результате getPublicPostsFromDatabase вызывается снова, что совсем не то, чего я хотел бы в идеале. Есть еще какие-нибудь предложения?

2. @Ritesh не могли бы вы пояснить, что вы подразумеваете под EventBus для управления загрузкой данных?

3. шина событий — это зависимость, в которой вы можете запускать событие и перехватывать событие в любом месте приложения, например: — andreas-schrade.de/2015/11/28 /…

Ответ №2:

Установите setOffscreenPageLimit, чтобы не загружать данные фрагмента again.so попробуйте эту строку ниже:

 viewPager.setOffscreenPageLimit(yourNooftab);
  

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

1. Я не думаю, что это сработает. Это потому, что моя первая вкладка будет загружена дважды, несмотря ни на что, даже если я установлю ограничение на страницу вне экрана равным 0.