我有一个用于BaseAdapter
的自定义ListView
。一行的通常布局看起来像第一张图片。
但是列表也可以包含第二行的字符串为空的项,如第二张图片,如果第二行的字符串长度等于0,则调用第二行的视图setVisibility(View.GONE)
方法。 / p>
当列表中填充了项目,因此需要滚动查看最底部的项目,然后向下滚动并且只有一行的项目,然后滚动回到顶部,其中一些是 - 订单项可能会丢失第二行,就像第三张图片一样。
当一个项目从列表中删除时会发生类似的事情 - 它所在的项目会获得已删除项目的高度 - 就像在第四张图片上一样(忘记彩色条形图)。
所以适配器似乎认为“Cookies”项与“Something”项目相同......或者其他东西。 为什么会这样?我该如何解决这个问题?
Another gallery to show exactly what happens
适配器代码:
public class CounterItemAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<CounterItem> data;
private SQLiteOpenHelper helper;
private static LayoutInflater inflater = null;
public CounterItemAdapter(Activity activity, ArrayList<CounterItem> data, SQLiteOpenHelper helper) {
this.activity = activity;
this.data = data;
this.helper = helper;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public CounterItem getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(convertView == null)
view = inflater.inflate(R.layout.counter_list_item, null);
TextView nameView = (TextView)view.findViewById(R.id.nameView);
TextView descView = (TextView)view.findViewById(R.id.descView);
final TextView countView = (TextView)view.findViewById(R.id.countView);
ImageButton plusButton = (ImageButton)view.findViewById(R.id.plusButton);
final CounterItem counterItem;
counterItem = data.get(position);
nameView.setText(counterItem.getName());
if(counterItem.getDesc().length() == 0){
descView.setVisibility(View.GONE);
Log.d(HomeActivity.DEBUG_TAG, "GONE " + counterItem.getName() + ", LENGTH " + counterItem.getDesc().length());
}else
descView.setText(counterItem.getDesc());
countView.setText(counterItem.getCount() + "");
plusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
counterItem.increment(helper.getWritableDatabase());
countView.setText(counterItem.getCount() + "");
}
});
View categoryView = view.findViewById(R.id.category);
String colors[] = {"#ff99cc00",
"#ff00ddff",
"#ffffbb33",
"#ffaa66cc",
"#ffcc0000"};
Random rand = new Random();
String color = colors[rand.nextInt(colors.length)];
categoryView.setBackgroundColor(Color.parseColor(color));
return view;
}
}
行布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:descendantFocusability="blocksDescendants"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/linearLayout" android:layout_centerVertical="true"
android:gravity="center_vertical" android:paddingLeft="12dp" android:paddingRight="12dp"
android:paddingBottom="8dp" android:paddingTop="8dp" android:id="@+id/linearLayout1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Counter name"
android:id="@+id/nameView"
android:textSize="16dp"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/descView"
android:textSize="16dp"
android:textColor="@color/dividerGrey"
android:text="wtf"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="@+id/linearLayout" android:gravity="center_vertical" android:layout_centerVertical="true"
android:paddingTop="8dp" android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="13"
android:id="@+id/countView"
android:textSize="30dp"
android:layout_marginRight="13dp" android:textColor="@color/dividerGrey"/>
<View android:layout_width="0.5dp" android:layout_height="48dp"
android:background="@color/dividerGrey" android:id="@+id/plusDivider"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/plusButton"
android:src="@drawable/ic_button_increment"
style="@android:style/Widget.Holo.Light.ActionButton"
android:contentDescription="@string/plus_button"/>
</LinearLayout>
</RelativeLayout>
答案 0 :(得分:1)
嗯,我想你在ListView中使用ViewHolder模式吧? 我不想尝试解释这个模式的整个用法,因为还有很多其他好的教程。
所以你描述的情况发生了,因为listAdapter重用了为每个对象充气的convertView,所以如果listview的最后一个对象为你的第二行有setVisibility(View.Gone),那么当你向上滚动所有其他的子对象时变得可见也会有可见性(View.Gone)。
一个简单的解决方法是为每行设置setVisibility 像这样:
if (convertView == null) {
convertView = (View) inflater.inflate(R.layout.view_item, null);
viewHolder = new ViewHolder();
viewHolder.itemName = (TextView) convertView.findViewById(R.id.item_name);
viewHolder.secondLine = (TextView) convertView.findViewById(R.id.second_line)
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
if(<-- your condition here-->){
secondLine.setVisibility(View.VISIBLE);
}
else{
secondLine.setVisibility(View.GONE);
}
现在您已经为适配器添加了代码,我相信您的错误就在这里:
if(counterItem.getDesc().length() == 0){
descView.setVisibility(View.GONE);
Log.d(HomeActivity.DEBUG_TAG, "GONE " + counterItem.getName() + ", LENGTH " + counterItem.getDesc().length());
}else {
**descView.setVisibility(View.VISIBLE);**
descView.setText(counterItem.getDesc());
}
你应该添加代码,如果需要的话,可以再次将其设置为可见,当代码消失时,它会永久消失。
<强>更新强>
另外针对您的第二个问题,每当您从列表视图中删除项目时,您应该从适配器中删除该项目并调用notifyDataSetChanged();以便适配器重新创建视图。