I have an scrollable list to which I am adding some records dynamically. It works very simple, I add records to ArrayList, than pass it to adapter. The problem is when I am scrolling, 3 first records always get loaded, than during scrolling first few records also gets loaded. But later i keep getting some random previous records (seems like according to the ArrayList which is correct). How can I force records to be loaded? I also read in other's articles that initializing layout="match_parent" could help, which I have done. I'm posting my code below.
public void addItem(String item) {
assets.add(0, item);
listView.setAdapter(adapter);
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<ListView
android:id="@ id/list_view"
android:layout_width="match_parent"
android:paddingRight="0sp"
android:layout_height="350dp" />
<Button
android:id="@ id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@ id/list_view"
android:onClick="save"
android:layout_marginLeft="24dp"
android:text="Zapisz"
android:backgroundTint="@color/colorPrimary"/>
My custom adapter class:
public class ListViewAdapter extends ArrayAdapter<String> {
ArrayList<String> list;
Context context;
public ListViewAdapter(Context context, ArrayList<String> items) {
super(context, R.layout.list_row, items);
this.context = context;
list = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = LayoutInflater.from(context);
convertView = mInflater.inflate(R.layout.list_row, parent, false);
TextView name = convertView.findViewById(R.id.name);
ImageView remove = convertView.findViewById(R.id.remove);
name.setText(list.get(position));
remove.setOnClickListener(view -> MainActivity.removeItem(position));
}
return convertView;
}
}
list_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15sp">
<TextView
android:id="@ id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="#000"
android:textSize="20sp"
android:layout_marginRight="30sp"/>
<ImageView
android:id="@ id/remove"
android:layout_width="22sp"
android:layout_height="22sp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="6sp"
android:src="@drawable/remove" />
</RelativeLayout>
CodePudding user response:
Update your getView() method like below, No need to reassign convertview when it is not null but you need to set new values to that position.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_row, parent, false);
}
TextView name = convertView.findViewById(R.id.name);
ImageView remove = convertView.findViewById(R.id.remove);
name.setText(list.get(position));
remove.setOnClickListener(view -> MainActivity.removeItem(position));
return convertView;
}
CodePudding user response:
Your adapter's getView()
is called for each row. However, convertView
will only be null for the first n views. After that, they are reused. Move your data population outside of the if so that it is guaranteed to be called for every row.
You should also consider using a RecyclerView
instead to improve performance. findViewById
is fairly expensive and the ViewHolder pattern can make scrolling smoother.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = LayoutInflater.from(context);
convertView = mInflater.inflate(R.layout.list_row, parent, false);
}
TextView name = convertView.findViewById(R.id.name);
ImageView remove = convertView.findViewById(R.id.remove);
name.setText(list.get(position));
remove.setOnClickListener(view -> MainActivity.removeItem(position));
return convertView;
}