-1

カスタム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");
    }
};

}

そして、次のようなコードを使用して、メインクラスからアイテムを追加します。

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);

}

これが発生したときにリストに別の項目を追加するまでは正常に機能します(上の行が空白であることに注意してください。複数の行を追加すると、最後の行を除くすべての行がこのように空白になります)。

何が起こっているのかアイデアはありますか?

スクリーンショット

4

3 に答える 3

5

いったい何をしているか?/やろうとしていますか?

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

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

最後のアイテムのみがレンダリングするビューを取得します!

(スクロールを有効にするために)100個のアイテムを追加してスクロールしてみてください!あなたはそれがどれほど素晴らしいかを見るでしょう。


解決策: convertViewがnullになるたびに、新しいビューを膨らませる必要があります。同じビューを返すと、getView呼び出された最後の位置が表示されます。

于 2012-06-18T11:27:34.613 に答える
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);

}

役に立ちますように

于 2012-06-18T11:40:25.647 に答える
0

myListModel = new ArrayList<MyItemModel>();メソッドの外側に移動したいsetUpList()場合があります。この方法では、呼び出すたびに新しい配列を作成しているsetUpList()ため、配列内のアイテムは常に 1 つだけです。配列宣言をメソッドの外に移動すると、アイテム配列に正しく追加されます

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);

}
于 2012-06-15T16:18:52.580 に答える