2017-01-12 4 views
3

Ich habe eine NavigationDrawer-Aktivität, die Fragmente verwendet. In einem meiner Fragmente möchte ich Daten aus der Firebase-Datenbank in eine RecyclerView laden.Android - Laden von Daten aus der Firebase-Datenbank in Fragment

Also habe ich eine ArrayList für die Objekte, die ich in der Datenbank gespeichert habe. Dann füge ich meiner Datenbankreferenz einen ValueEventListener hinzu, wo ich die Objekte aus der Datenbank der Array-Liste hinzufüge. Und dann gebe ich die ArrayList dem RecyclerView Adapter, der die Liste mit meinen Objekten erstellen soll.

Wenn ich addListenerForSingleValueEvent verwende, funktioniert es nie, ich bekomme immer eine leere RecyclerView. Wenn ich addValueEventListener benutze, funktioniert es nicht am Anfang, aber wenn ich die Ausrichtung meines Telefons auf Landschaft umstelle, erscheinen die Daten plötzlich. Und wenn ich zurück zur normalen Orientierung gehe, ist es immer noch da. Aber nicht am Anfang, wenn ich das Fragment öffne.

Hier mein Code des Fragments Klasse:

public class LogFragment extends Fragment { 

    private RecyclerView recyclerView; 
    private RecyclerView.Adapter rvAdapter; 
    private RecyclerView.LayoutManager rvLayoutManager; 
    private ArrayList<LogEntry> entries; 

    private DatabaseReference databaseReference; 
    private DatabaseReference logReference; 
    private FirebaseAuth firebaseAuth; 
    private FirebaseUser firebaseUser; 

    public LogFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_log, container, false); 

     databaseReference = FirebaseDatabase.getInstance().getReference(); 
     firebaseAuth = FirebaseAuth.getInstance(); 
     firebaseUser = firebaseAuth.getCurrentUser(); 

     loadEntries(); 

     recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); 
     rvLayoutManager = new LinearLayoutManager(getActivity()); 
     recyclerView.setLayoutManager(rvLayoutManager); 

     rvAdapter = new RvAdapter(entries); 
     recyclerView.setAdapter(rvAdapter); 

     // Inflate the layout for this fragment 
     return rootView; 
    } 

    private void loadEntries(){ 
     entries = new ArrayList<>(); 
     logReference = databaseReference.child("log").child(firebaseUser.getUid()); 
     ValueEventListener valueEventListener = new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 

       for(DataSnapshot ds : dataSnapshot.getChildren()){ 
        entries.add(ds.getValue(LogEntry.class)); 
       } 

      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       Log.w("LogFragment", "loadLog:onCancelled", databaseError.toException()); 
      } 
     }; 
     logbuchReference.addValueEventListener(valueEventListener); 

    } 
} 

Und hier ist mein RvAdapter.java:

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> { 

    private ArrayList<LogEntry> entries; 

    public RvAdapter(ArrayList<LogEntry> entries){ 
     this.entries = entries; 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.log_entry_item, null); 

     return new MyViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(MyViewHolder holder, int position) { 

     SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); 
     SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); 

     holder.tvAction.setText(entries.get(position).action); 
     holder.tvDate.setText(dateFormat.format(entries.get(position).date)+"\n"+timeFormat.format(entries.get(position).date)); 
     holder.ivIcon.setImageResource(entries.get(position).icon); 

     holder.itemView.setOnClickListener(new View.OnClickListener(){ 

      @Override 
      public void onClick(View v) { 
       // Do something 
      } 
     }); 

    } 

    @Override 
    public int getItemCount() { 
     return entries.size(); 
    } 

    public class MyViewHolder extends RecyclerView.ViewHolder { 

     TextView tvAction, tvDate; 
     ImageView ivIcon; 

     public MyViewHolder(View itemView) { 
      super(itemView); 
      tvAction = (TextView) itemView.findViewById(R.id.tvAction); 
      tvDate = (TextView) itemView.findViewById(R.id.tvDate); 
      ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon); 
     } 
    } 
} 

Und hier meine LogEntry.java:

public class LogEntry { 

    public String action; 
    public Date date; 
    public int icon; 
    public String message; 

    public LogEntry() {} 

    public LogEntry(String action, Date date, int icon, String message) { 
     this.action = action; 
     this.date = date; 
     this.icon = icon; 
     this.message = message; 
    } 
} 

Jemand wissen, was könnte das Problem sein?

EDIT:

Als ich die Arraylist gleich nach dem für System.out.prinln() ich die Daten erhalten. So funktioniert das Laden der Daten aus der Datenbank. Aber die Präsentation der Daten funktioniert nicht.

Antwort

3

Firebase ist asynchron. Legen Sie den Adapter fest oder benachrichtigen Sie ihn über den Rückruf.

ValueEventListener valueEventListener = new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 

      for(DataSnapshot ds : dataSnapshot.getChildren()){ 
       entries.add(ds.getValue(LogEntry.class)); 
      } 

      // Declare adapter and set here 

      // OR... adapter.notifyDataSetChanged(); 

     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      Log.w("LogFragment", "loadLog:onCancelled", databaseError.toException()); 
     } 
    }; 

Genauer gesagt,

loadEntries(); // ... Doing stuff in the background 

    recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); 
    rvLayoutManager = new LinearLayoutManager(getActivity()); 
    recyclerView.setLayoutManager(rvLayoutManager); 

    rvAdapter = new RvAdapter(entries); // This is still empty, probably 
    recyclerView.setAdapter(rvAdapter); 

    // entries.add() called later, but adapter never notified 
1

können Sie https://github.com/firebase/FirebaseUI-Android verwenden, dieses Problem zu lösen.

ListView messagesView = (ListView) findViewById(R.id.messages_list); 

DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); 

mAdapter = new FirebaseListAdapter<Chat>(this, Chat.class, android.R.layout.two_line_list_item, ref) { 
    @Override 
    protected void populateView(View view, Chat chatMessage, int position) { 
     ((TextView)view.findViewById(android.R.id.text1)).setText(chatMessage.getName()); 
     ((TextView)view.findViewById(android.R.id.text2)).setText(chatMessage.getText()); 

    } 
}; 
messagesView.setAdapter(mAdapter); 

Viel Glück

folgen ein wenig Code, den Sie ...

helfen !!!

Verwandte Themen