brent
brent

Reputation: 131

Instantly updating UI

I have a game lobby that adds a join button to the screen when someone creates a game. The button is added, but it doesn't appear until you leave and re-enter the page. This is the code that is adding the button and it's supposed to be updating the RecyclerView that stores the button.

    FCGames.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            numGames = (int) dataSnapshot.getChildrenCount();

               for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    gm = ds.getValue(GameMaker.class);
                    openGames.add(gm.getUser1().getUserName());
                }

            adapter.notifyDataSetChanged();

        }

So I think the issue is with the

adapter.notifyDataSetChanged()

But I am not entirely sure. I added that piece of code inside the for loop but that didn't change anything either.

Upon further investigation, I realized that the openGames List, which is simply defined at the top of the class as

ArrayList<String> openGames = new ArrayList<>();

Is not updating either until you refresh the page

Any advice?


I have looked through some things that @Puff said and have added this to my code. I have changed my listener statement to this

        FCGames.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                updateUI(new ListCallback() {
                        @Override
                        public void onCallback(List<String> value) {
                            Toast.makeText(FlipCoinLobby.this, "it worked", Toast.LENGTH_SHORT).show();
                        }
                    });
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

And have added this as my callback.

    public interface ListCallback {
    void onCallback(List<String> value);
}

And then I created this statement to update my user interface.

    public void updateUI(final ListCallback callBack) {
    FCGames.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            numGames = (int) dataSnapshot.getChildrenCount();

            ArrayList<String> openGames = new ArrayList<>();

            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                gm = ds.getValue(GameMaker.class);
                openGames.add(gm.getUser1().getUserName());
            }

            callBack.onCallback(openGames);

            adapter.notifyDataSetChanged();

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

So that functions correctly, but it still does not update the UI immediately. I must have done something wrong. Can anyone find a mistake I have made?

Also, I am trying to call my openGames ArrayList elsewhere, in a RecyclerView instance but cannot figure out exactly how to call it when I don't make the variable global.

This instance is in my onCreateMethod() and I am not sure what to put in place of 'openGames'

adapter = new MyRecyclerViewAdapter(this, openGames);

Hoping to get some help!

Upvotes: 0

Views: 62

Answers (2)

Riccardo Fassina
Riccardo Fassina

Reputation: 106

This is what i have done to refresh the matchmaking when the user isn't already connected into the ROOM :

  Matchmaking.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //nel caso ci siano delle modifiche alla tabella
                //se il match non � stato trovato e Account � stato verificato
                if(accountFound){
                    //azzero la Lista
                    List_party = new ArrayList<>();
                    Id_rooms = new ArrayList<>();
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    //sempre se matchfound non � stato trovato
                    if (!currentwithID.getMatch_found()) {
                        //prendo la quantit� di figli presenti
                        size = Integer.parseInt(String.valueOf(dataSnapshot.getChildrenCount()));
                        //inserisco all'interno della variabile CT il valore di ogni figlio
                        ct = ds.getValue(Class_party.class);
                        // e se � il numero di giocatori == 1 e la partita non � iniziata e finita in modo anomalo
                        if (ct.getNumberOfPlayers() == 1 && !ct.getStart() && ct.getCorrect_end() && ct.getAccessible()) {
                            //aggiungo l'id della room alla lista
                            //Inserisco alla list_party l'intero oggetto
                            Id_rooms.add(ct.getId());
                            List_party.add(ct);
                        }

                        Toast.makeText(HomeActivity.this, "Room List Updated", Toast.LENGTH_SHORT).show();
                    }
                }
                }
            }

Hope it helps :D

Upvotes: 0

Bro Nicholas
Bro Nicholas

Reputation: 223

Declare the Array list inside the listener as below

FCGames.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        numGames = (int) dataSnapshot.getChildrenCount();
          ArrayList<String> openGames = new ArrayList<>();

           for(DataSnapshot ds : dataSnapshot.getChildren()) {
                gm = ds.getValue(GameMaker.class);
                openGames.add(gm.getUser1().getUserName());
            }
             //Pass the object to a method in your program to update UI.
            updateUi(openGames);
           //Reload the adapter!


        adapter.notifyDataSetChanged();

    }

Upvotes: 1

Related Questions