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.
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
.