Search code examples
javaandroidadapterandroid-adapter

Android Studio with Java: ArrayAdapter not working correctly


I'm making an app in which the user can enter a few items and have it displayed as he adds items. I'm using an adapter to achieve this but instead of showing me a neat list with items, the adapter creates a list of several views repeating themselves (i.e Instead of just using the given TextView as a Template for the entry in the listview, it uses all views in that activity).

Here is the code:

This is from the createEntry class. This code initiates the adapter and loads the previous entries for a particular day. It send adds them all to the adapter.

public void loadEntries() {

   events = new ArrayList<>();
   adapter = new EntryAdapter(this, entries);
   ListView listView = findViewById(R.id.entry_list);
   listView.setAdapter(adapter);

    new AsyncTask<Void, Void, List<String>>() {

        @Override
        protected List<String> doInBackground(Void... voids) {
            return appDB.entryDao().getEntriesFromDate(day, monthNum, year);
        }

        @Override
        protected void onPostExecute(List items) {
            generateEntryTable(items);
        }
    }.execute();

}

public void generateEntryTable(List items) {

    for (int i = 0; i < items.size(); i++) {
        adapter.add(new TableEntries(year, monthNum, day, entryContent));
    }

}

This is my custom EntryAdapter class:

public class EntryAdapter extends ArrayAdapter<Entry> {

    public EntryAdapter(Context context, ArrayList<Entry> entries) {
        super(context, 0, entries);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup container {

        Entry entry = getItem(position);

        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.activity_create_event, container, false);
        }

        TextView newEntry = convertView.findViewById(R.id.new_entry);
        newEntry.setText(entry.getContent());
        return convertView;

}
}

This is the XML-file:

<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:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CreateEntry">

<TextView
    android:id="@+id/date"
    android:layout_width="222dp"
    android:layout_height="44dp"
    android:layout_marginStart="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginTop="24dp"
    android:layout_marginEnd="215dp"
    android:layout_marginRight="215dp"
    android:layout_marginBottom="685dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.0" />

<LinearLayout
    android:id="@+id/linearLayout"
    android:layout_width="403dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="116dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginBottom="200dp"
    android:background="#5CFF9800"
    android:orientation="vertical"
    app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/date"
    app:layout_constraintVertical_bias="0.0">

    <TextView
        android:id="@+id/textView3"
        android:layout_width="112dp"
        android:layout_height="35dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="276dp"
        android:layout_marginRight="276dp"
        android:layout_marginBottom="8dp"
        android:text="@string/event"
        android:textSize="24sp" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/addEvents"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:contentDescription="@string/add_events"
            android:cropToPadding="true"
            android:onClick="addEvent"
            android:scaleType="fitStart"
            android:tint="#FF3F02"
            app:srcCompat="@android:drawable/ic_menu_add" />

        <EditText
            android:id="@+id/addEventsPrompt"
            android:layout_width="353dp"
            android:layout_height="30dp"
            android:background="@android:color/transparent"
            android:clickable="true"
            android:freezesText="false"
            android:gravity="start|fill|center_vertical"
            android:hint="@string/startTyping"
            android:inputType="textShortMessage|textLongMessage|textMultiLine|textPersonName|text"
            android:textAllCaps="false"
            android:textAppearance="@style/TextAppearance.AppCompat.Display1"
            android:textSize="14sp" />

    </TableRow>

    <ListView
        android:id="@+id/event_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:id="@+id/entry_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView

            android:id="@+id/new_entry"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>


<LinearLayout
    android:id="@+id/linearLayout2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginBottom="156dp"
    android:orientation="vertical"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent">

    <TextView
        android:id="@+id/toDoTitle"
        android:layout_width="102dp"
        android:layout_height="33dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="322dp"
        android:layout_marginRight="322dp"
        android:text="@string/to_do"
        android:textSize="24sp" />

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageButton
            android:id="@+id/addToDo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="8dp"
            android:background="#00FFFFFF"
            android:contentDescription="@string/add_to_dos"
            android:onClick="addToDo"
            android:scaleType="fitStart"
            android:tint="#FF3B00"
            app:srcCompat="@android:drawable/ic_menu_add" />

        <EditText
            android:id="@+id/addToDoPrompt"
            android:layout_width="344dp"
            android:layout_height="32dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:layout_weight="100"
            android:autofillHints=""
            android:background="@android:color/transparent"
            android:gravity="start|fill_horizontal|center_vertical"
            android:hint="@string/startTyping"
            android:inputType="textShortMessage|textLongMessage|textMultiLine|text"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/new_to_do"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </TableRow>
</LinearLayout>

If you need to see any other code, please let me know. The difference in usage of adapter to the tutorials that I have seen is that, in my app, the listview is not the only view displayed in the activity so that may be the/a problem.


Solution

  • You're going about this in the wrong manner. In your EntryAdapter:

    @Override
    public View getView(int position, View convertView, ViewGroup container {
    
        Entry entry = getItem(position);
    
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext())
                .inflate(R.layout.activity_create_event, container, false);
        }
    
    ...
    

    In that inflate statement you are inflating the entire XML layout for your Activity (R.layout.activity_create_event) for every row of your ListView. Instead, you should be using a much simpler layout containing just your TextView in a separate layout XML file, for example let's call this res/layout/list_row.xml:

    <LinearLayout 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"
        android:orientation="vertical">
    
            <TextView
                android:id="@+id/new_entry"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:text="Placeholder Text" />
    </LinearLayout>
    

    Then replace the layout you're inflating in getView() like so:

    @Override
    public View getView(int position, View convertView, ViewGroup container {
    
        Entry entry = getItem(position);
    
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext())
                .inflate(R.layout.list_row, container, false);
        }
    
    ...
    

    I'd also recommend looking into RecyclerView as that has now superceded ListView.