0

I started off by building a ListView that contains multiple TextViews without Firebase and that worked well (Note: I stored my data in String arrays). Then I created a ListView (ArrayAdapter) with a single TextView with Firebase and that worked well too (Note: I stored my data in an ArrayList). But once I merged the two projects together, it didn't work (Note: Multiple TextViews exist in this project but I'm only trying to populate my first TextView for now). My app just closes as soon as it tries to open.

UPDATE: In the separate project where I created a ListView (ArrayAdapter) with a single TextView with Firebase, I used .notifyDataSetChanged() instead. When I use .notify() in that project, it no longer works. Is my use of .notify() in this project causing the issue? I cannot seem to use .notfiyDataSetChanged in this project.

Here is my activity_main which contains the ListView:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/eventsListView"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_marginStart="32dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="1dp"
        android:scrollbars="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Here is my activity_list_view which outlines the view of the ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/eventTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_vertical"
            android:paddingTop="5dp"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/eventDetails"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:paddingBottom="5dp"
            android:textSize="16sp"
            android:textStyle="italic" />

        <TextView
            android:id="@+id/eventDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_vertical"
            android:paddingBottom="5dp"
            android:textSize="16sp" />

    </LinearLayout>

</LinearLayout>

Here is my MainActivity:

package com.example.firebase_listview_2;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ListView eventsList;
    DatabaseReference dawnEvents;
    ArrayList<String> titleArray = new ArrayList<>();
    ArrayList<String> eventStartArray = new ArrayList<>();
    ArrayList<String> eventFinishArray = new ArrayList<>();
    ArrayList<String> eventGenderArray = new ArrayList<>();
    ArrayList<String> eventAgeArray = new ArrayList<>();
    ArrayList<String> descriptionArray = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ListAdapter adapter = new com.example.firebase_listview_2.ListAdapter(this, titleArray, eventStartArray, eventFinishArray, eventGenderArray, eventAgeArray, descriptionArray);
        eventsList = findViewById(R.id.eventsListView);
        eventsList.setAdapter(adapter);

        dawnEvents = FirebaseDatabase.getInstance().getReference("Timetable/Ladybridge High School, Bolton, UK/Date/2019-11-30/Events/Spanish Lesson");
        dawnEvents.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                String value = dataSnapshot.getValue(String.class);
                titleArray.add(value);
                adapter.notify(); // In the separate project where I created a ListView (ArrayAdapter) with a single TextView with Firebase, I used .notifyDataSetChanged() instead. When I use .notify() in that project, it no longer works. Is my use of .notify() in this project causing the issue? I cannot seem to use .notfiyDataSetChanged in this project.
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

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

            }
        });
    }
}

Here is my ListAdapter:

package com.example.firebase_listview_2;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;

public class ListAdapter extends ArrayAdapter<String> {

    private final Activity context;
    private final ArrayList<String> titleArray;
    private final ArrayList<String> eventStartArray;
    private final ArrayList<String> eventFinishArray;
    private final ArrayList<String> eventGenderArray;
    private final ArrayList<String> eventAgeArray;
    private final ArrayList<String> descriptionArray;

    public ListAdapter(Activity context, ArrayList<String> titleArray, ArrayList<String> eventStartArray, ArrayList<String> eventFinishArray, ArrayList<String> eventGenderArray, ArrayList<String> eventAgeArray, ArrayList<String> descriptionArray) {
        super(context, R.layout.activity_list_view, titleArray);

        this.context = context;
        this.titleArray = titleArray;
        this.eventStartArray = eventStartArray;
        this.eventFinishArray = eventFinishArray;
        this.eventGenderArray = eventGenderArray;
        this.eventAgeArray = eventAgeArray;
        this.descriptionArray = descriptionArray;
    }

    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.activity_list_view, null, true);

        TextView eventTitle = rowView.findViewById(R.id.eventTitle);
        TextView eventDetails = rowView.findViewById(R.id.eventDetails);
        TextView eventDescription = rowView.findViewById(R.id.eventDescription);

        eventTitle.setText(titleArray.get(position));
        String eventDetailsConcat = eventStartArray.get(position) + "-" + eventFinishArray.get(position) + ", " + eventGenderArray.get(position) + ", " + eventAgeArray.get(position);
        eventDetails.setText(eventDetailsConcat);
        eventDescription.setText(descriptionArray.get(position));

        return rowView;
    }
}

This is the relevant sample of my Firebase database structure:

Timetable
   Ladybridge High School, Bolton, UK
      Date
         2019-11-30
            Spanish Lesson
               Age: "All ages"
               Description: "Example description for Spanish lesson"
               Finish: "18:00"
               Gender: "Male and female"
               Start: "16:00"
               Title: "Spanish for Beginners"
Raf A
  • 179
  • 1
  • 12

2 Answers2

0

In your Firebase event listener, you are adding values just in titleArray. The app most probably throws a NullPointerException on this line:

 String eventDetailsConcat = eventStartArray.get(position) + "-" + eventFinishArray.get(position) + ", " + eventGenderArray.get(position) + ", " + eventAgeArray.get(position);

from ListAdapter.

  • The arrays used in that particular line are all empty for now. I commented them out anyway to see if it was the cause of the error but it still doesn't work unfortunately. I've updated my question to clarify that even though multiple TextViews are in my current project, I'm only trying to populate the first one from Firebase. – Raf A Dec 05 '19 at 15:10
0

Blackbelts answer in this question resolved the error: Error: Cannot Resolve notifyDataSetChanged(); Android

To summarise: "notifyDataSetChanged is not a method of ListAdapter, but of BaseAdapter, (ArrayAdapter is a subclass of BaseAdapter)"

Code change from:

adapter.notify();

Code change to:

((BaseAdapter)adapter).notifyDataSetChanged();
Raf A
  • 179
  • 1
  • 12