0

我有一个BaseAdapter用于ListView. 行的通常布局看起来像第一张图片。

画廊在这里

但是列表也可以包含第二行字符串为空的项目,如第二张图片,如果第二行字符串的长度等于 0,setVisibility(View.GONE)则调用第二行视图的方法。

当列表中填满了项目时,需要滚动查看最底部的项目,向下滚动发现只有一行的项目,然后滚动回顶部,一些两行项目可以失去他们的第二行,就像在第三张照片上一样。

当从列表中删除一个项目时会发生类似的事情 - 位于其位置的项目获得已删除项目的高度 - 就像第四张图片一样(忘记彩色条)。

所以似乎适配器认为“Cookies”项目与“Something”项目......或其他东西相同。为什么会这样?我该如何解决?

另一个画廊可以准确展示发生了什么

适配器代码:

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

1 回答 1

1

好吧,我想您在 ListView 中使用 ViewHolder 模式对吗?我不想尝试解释这种模式的全部用法,因为还有许多其他好的教程。

所以你描述的情况发生了,因为 listAdapter 重用了为每个对象膨胀的 convertView 所以如果你的 listview 的最后一个对象为你的第二行设置了 setVisibility(View.Gone) 那么当你向上滚动所有其他可见的孩子时也将具有可见性(View.Gone)。

一个简单的解决方法是为每一行设置可见性,如下所示:

    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(); 为了让适配器重新创建视图。

于 2013-07-26T23:20:30.117 回答