My app has a dialog that shows a listview of favorite balls an user has saved. Each item of the listview should have 6 balls.
String action = "favoriteId ASC";
Favorite = Select.from(Favorites.class).where(Condition.prop("favoritemode").eq(""+ Constants.mode)).orderBy(action).list();
FavAdapter adapter = new FavAdapter(LuckyNumber.this, Favorite);
lv_content.setAdapter(adapter);
public class FavAdapter extends ArrayAdapter<Favorites> {
public FavAdapter(Context context, List<Favorites> fav) {
super(context, 0, fav);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Favorites fav = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_favorite, parent, false);
}
final LinearLayout ll_ball2 = (LinearLayout) convertView.findViewById(R.id.ll_ball2);
ImageView btn_use = (ImageView) convertView.findViewById(R.id.btn_use);
ImageView btn_delete = (ImageView) convertView.findViewById(R.id.btn_delete);
TextView tv_check = (TextView) convertView.findViewById(R.id.tv_check);
String result = fav.getfavoriteslot();
String [] temp = null;
temp = result.split("--");
String ss = "";
for (int m=0; m< temp.length; m++)
{
try
{
ss = ss + "." + temp[m] ;
ImageView slot_ball = new ImageView(LuckyNumber.this);
slot_ball.setEnabled(false);
slot_ball.setImageBitmap(return_bm (Integer.valueOf(temp[m])+""));
slot_ball.setScaleType(ImageView.ScaleType.FIT_XY);
ll_ball2.addView(slot_ball);
}
catch (Exception ex)
{
}
}
tv_check.setText(""+ss + "...Size=" + temp.length + "Childview=" + ll_ball2.getChildCount());
return convertView;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/ll_row2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:orientation="horizontal" >
<RelativeLayout
android:id="@+id/keyboard_frame_btn_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:orientation="horizontal"
android:splitMotionEvents="false" >
<LinearLayout
android:id="@+id/ll_ball2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="left|center_vertical"
android:gravity="left|center_vertical"
android:splitMotionEvents="false">
</LinearLayout>
<TextView
android:id="@+id/tv_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_ball2">
</TextView>
<ImageButton
android:id="@+id/btn_use"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="@dimen/dp2"
android:layout_toLeftOf="@+id/btn_delete"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/btn_use_selector" />
<ImageButton
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:layout_margin="@dimen/dp2"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/btn_delete_selector" />
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/row3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp2"
android:gravity="center"
android:splitMotionEvents="false" >
<View
android:id="@+id/view1"
android:layout_width="fill_parent"
android:layout_height="2px"
android:layout_margin="@dimen/dp5"
android:background="@color/black" />
</RelativeLayout>
</LinearLayout>
tv_check
shows that for each favorite slots, indeed it knows each slot has 6 balls (size =6). It appears that it is the listview problem inflating wrongly to the first item. The first row of listview shows many repeated items, while the balls starting from the second row are in order. Each row should have 6 balls. The getChildCount shows a pattern as follows:
For 3 slots saved, childcount of first row is 150 (=6balls*3slots*8 + 6).
For 4 slots saved, childcount of first row is 198 (=6balls*4slots*8 + 6).
For 5 slots saved (as in screen capture below), childcount of first row is 246 (=6balls*5slots*8 + 6).
It seems that getView()
in general - and especially getView(0) - will be called more often than there are items in the data list. This is not a bug of ListView
or ArrayAdapter
, it's simply the way things are.
In your implementation of getView()
, you only add child View
s to the LinearLayout
, you never remove them.
So if a row is recycled, the number of child View
s will become too large. This will happen not only for the first row but also when you scroll up and down (if the list is long enough) and so cause more rows to be recycled.
Since each row should have six balls, you can add the six ImageView
s to each LinearLayout
right after the row has been inflated (or even make them part of the layout xml file) and later on loop through the ImageView
s to exchange the Bitmap
depending on the data for the current position.