W poniższym kodzie próbowałem odczytać dane z Firebase i użyć ich do dynamicznego tworzenia widoków kart, ale kiedy program się uruchamia, ArrayList jest pusta, gdy klikam trzecią kartę i wracam do pierwszej. Po kilku dniach od znalezienia problemu sam nie potrafiłem go rozwiązać. MainScreen.java:

public class MainScreen extends AppCompatActivity {

private SectionsPagerAdapter mSectionsPagerAdapter;

private ViewPager mViewPager;
private static final String TAG = "MainScreen";
public List<BusNumber> jaratok= new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_screen);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    mViewPager = findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    TabLayout tabLayout = findViewById(R.id.tabs);
    tabLayout.getTabAt(0).setText("Járatok");
    tabLayout.getTabAt(1).setText("Megállók");
    tabLayout.getTabAt(2).setText("Tervező");

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("bus_number");
    myRef.addValueEventListener((new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            jaratok = new ArrayList<>();
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                jaratok.add(new BusNumber(ds.child("CodeNumber").getValue(String.class),ds.child("BusRouteName").getValue(String.class)));
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.w("TAG","Failed to read data.",databaseError.toException());
        }
    }));
    mSectionsPagerAdapter.notifyDataSetChanged();

    mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Fejlesztés alatt", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

}
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {

        switch(position)
        {
            case 0:
                JaratokTab1 tab1 = new JaratokTab1();
                return tab1;
            case 1:
                MegallokTab2 tab2 = new MegallokTab2();
                return tab2;
            case 2:
                TervezoTab3 tab3 = new TervezoTab3();
                return tab3;

            default:
                return null;
        }
    }

}

JaratokTab1.java:

public class JaratokTab1 extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.jaratok_tab1, container, false);
    MainScreen m2 = (MainScreen) getActivity();
    for (BusNumber n : m2.jaratok) {
        Log.d("Ertek: ", n.getName());
    }
    CardView cardView = new CardView(getContext());
    TextView tv = new TextView(getContext());
    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
    tv.setLayoutParams(params);
    cardView.setLayoutParams(params);
    cardView.setVisibility(View.VISIBLE);
    cardView.setCardElevation(9);
    cardView.setPadding(15, 15, 15, 15);
    cardView.setRadius(9);
    tv.setTextColor(Color.RED);
    tv.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
    cardView.addView(tv);
    LinearLayout linearLayout = rootView.findViewById(R.id.linearID);
    linearLayout.setPadding(60,15,50,30);
    linearLayout.addView(cardView);
    return rootView;
}
//also tried this:
   /* @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        MainScreen m2 = (MainScreen) getActivity();
        for (BusNumber n : m2.jaratok) {
            Log.d("Ertek: ", n.getName());
        }
    }*/
}
0
Gergő Nagy 18 listopad 2018, 20:13

1 odpowiedź

Najlepsza odpowiedź

Zanim przejdziesz przez m2.jaratok, dane nie są jeszcze dostępne i dlatego Twoja lista jest pusta. Interfejsy API Firebase to asynchronous, co oznacza, że ​​metoda onDataChange() powraca natychmiast po jej wywołaniu, a wywołanie zwrotne z zadania, które zwraca, zostanie wywołane jakiś czas później.

Nie ma gwarancji, jak długo to potrwa, może upłynąć od kilkuset milisekund do kilku sekund, zanim dane będą dostępne i mogą być używane. Ponieważ ta metoda zwraca natychmiast, twoja lista jaratok, której próbujesz użyć poza wywołaniem zwrotnym, jest pusta.

Zasadniczo próbujesz użyć wartości synchronicznie z interfejsu API, który jest asynchroniczny. To nie jest dobry pomysł. Interfejsy API należy obsługiwać asynchronicznie zgodnie z przeznaczeniem.

Szybkim rozwiązaniem tego problemu byłoby użycie listy jaratok tylko wewnątrz metody onDataChange(), w przeciwnym razie polecam zobaczyć ostatnią część mojej odpowiedzi z tego post, w którym wyjaśniłem, jak to można to zrobić za pomocą niestandardowego wywołania zwrotnego. Możesz również obejrzeć ten film, aby uzyskać lepsze zrozumienie.

0
Alex Mamo 19 listopad 2018, 15:15