向ListView添加新行会使其上方的行消失

时间:2012-06-15 16:08:25

标签: android listview baseadapter

我有一个使用自定义BaseAdapter(MyBaseAdapter)填充的ListView:

public class MyBaseAdapter extends BaseAdapter
{

    private View renderer;

    List<MyItemModel> items;

    public MyBaseAdapter(View renderer) {
        this.renderer = renderer;
    }

    public void setModel(List<MyItemModel> items)
    {

        this.items = items;
        notifyDataSetChanged();
    }


    @Override
    public int getCount()
    {

        return items != null ? items.size() : 0;
    }


    @Override
    public Object getItem(int position)
    {

        return items != null ? items.get(position) : null;
    }


    @Override
    public long getItemId(int position)
    {

        return items != null ? items.get(position).id : -1;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        if (convertView == null)
        {
            convertView = renderer;
        }
        MyItemModel item = items.get(position);
        // replace those R.ids by the ones inside your custom list_item layout.
        TextView timeText = (TextView) convertView.findViewById(R.id.timeText);
        timeText.setText(item.time);

        ToggleButton button = (ToggleButton) convertView.findViewById(R.id.toggleButton);
        button.setOnClickListener(item.listener);

        ImageView coinImage = (ImageView) convertView.findViewById(R.id.coinImage);
        coinImage.setImageResource(R.drawable.ic_refresh);

        return convertView;
    }

}

使用这些项目填充

public class MyItemModel
{

String time;
long id;

OnClickListener listener = new OnClickListener(){
    @Override
    public void onClick(View v) {
        Log.d("app", "whatever");
    }
};

}

我使用以下代码从我的Main类添加项目:

private void setUpList()
{

    myListModel = new ArrayList<MyItemModel>();

    MyItemModel item = new MyItemModel();
    item.time = "12:00";
    item.id = 0;
    myListModel.add(item);

   //if I add a few more items here, it still only shows the bottom one

    LayoutInflater li = getLayoutInflater();
                      //alarm_list_item is a table row 
    View view = li.inflate(R.layout.alarm_list_item, null);

    adapter = new MyBaseAdapter(view);
    adapter.setModel(myListModel);
    setListAdapter(adapter);
    listView = getListView();
    listView.setTextFilterEnabled(true);

}

这样可以正常工作,直到我在列表中添加另一个项目时(注意它上面的行是空白的。如果我添加多行,则除了最后一行之外的所有行都是空白的。)

任何想法发生了什么?

screenshot

3 个答案:

答案 0 :(得分:5)

你到底在做什么? /尝试做什么?

@Override
public View getView(int position, View convertView, ViewGroup parent)
{

    if (convertView == null)
    {
        convertView = renderer;
    }
    //...//
}

只有你的最后一个项目才能获得渲染视图!

尝试添加100个项目(以启用滚动)并滚动!你会看到它有多棒。


解决方案: 每次convertView为null时,您都必须为新视图充气。返回相同的视图将显示调用getView的最后位置。

答案 1 :(得分:2)

我不知道你的问题的背景,但你的适配器接缝中的成员渲染器有点奇怪。它使 listView 中的所有项目视图成为第一个创建的itemView。

我认为您可以尝试修改 getView(int position,View convertView,ViewGroup parent)方法,如下所示:

public class MyBaseAdapter extends BaseAdapter
{

    //private View renderer;
    private Context mContext;


    List<MyItemModel> items;

    public MyBaseAdapter(Context context) {
        this.mContext = context;
    }

    public void setModel(List<MyItemModel> items)
    {

        this.items = items;
        notifyDataSetChanged();
    }


    @Override
    public int getCount()
    {

        return items != null ? items.size() : 0;
    }


    @Override
    public Object getItem(int position)
    {

        return items != null ? items.get(position) : null;
    }


    @Override
    public long getItemId(int position)
    {

        return items != null ? items.get(position).id : -1;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        if (convertView == null)
        {
            LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = li.inflate(R.layout.alarm_list_item, null);
        }
        MyItemModel item = items.get(position);
        // replace those R.ids by the ones inside your custom list_item layout.
        TextView timeText = (TextView) convertView.findViewById(R.id.timeText);
        timeText.setText(item.time);

        ToggleButton button = (ToggleButton) convertView.findViewById(R.id.toggleButton);
        button.setOnClickListener(item.listener);

        ImageView coinImage = (ImageView) convertView.findViewById(R.id.coinImage);
        coinImage.setImageResource(R.drawable.ic_refresh);

        return convertView;
    }

}

并在 setUpList()中,在构建适配器时将主机活动作为参数传递:

private void setUpList(){

    MyItemModel item = new MyItemModel();
    item.time = "12:00";
    item.id = 0;
    myListModel.add(item);

    LayoutInflater li = getLayoutInflater();
                  //alarm_list_item is a table row 
    View view = li.inflate(R.layout.alarm_list_item, null);

    //adapter = new MyBaseAdapter(view);
    adapter = new MyBaseAdapter(Activity.this);
   adapter.setModel(myListModel);
    setListAdapter(adapter);
    listView = getListView();
    listView.setTextFilterEnabled(true);

}

愿它有所帮助

答案 2 :(得分:0)

您可能希望将myListModel = new ArrayList<MyItemModel>();方式移出setUpList()方法,按照您的方式移动,每次调用setUpList()时都要创建一个新数组,这样您只有一个项目整个数组,如果你在方法之外移动数组声明,这些项将被正确地添加到数组

myListModel = new ArrayList<MyItemModel>();

private void setUpList(){

    MyItemModel item = new MyItemModel();
    item.time = "12:00";
    item.id = 0;
    myListModel.add(item);

    LayoutInflater li = getLayoutInflater();
                  //alarm_list_item is a table row 
    View view = li.inflate(R.layout.alarm_list_item, null);

    adapter = new MyBaseAdapter(view);
    adapter.setModel(myListModel);
    setListAdapter(adapter);
    listView = getListView();
    listView.setTextFilterEnabled(true);

}