且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ListView控件与ArrayAdapter和ViewHolder添加图标到错误的项目

更新时间:2023-11-18 10:49:52

更新: ViewHolder 只是为了持有引用到组件意见里面的项目布局。这有助于避免调用的开销 findViewById 渲染每一个组件在复杂的项目布局由多个部分组成(如的TextView 的ImageView 在这种情况下)。

我固定它通过使用一个程序(称为 getSex )来检索性数据,并设置所有视图数据,包括外部的图标如 - 其他块。

工作code现在看起来是这样的:

 如果(空== convertView){
    Log.i(安迪,位置不是previously使用,所以坐大);
    convertView = inflater.inflate(R.layout.player_simple_list,NULL);

    //创建一个ViewHolder和存储引用的两个孩子意见
    //我们希望将数据绑定到。
    持有人=新ViewHolder();
    holder.text =(TextView中)convertView.findViewById(R.id.label);
    holder.icon =(ImageView的)convertView.findViewById(R.id.icon);
    convertView.setTag(保持器);
} 其他 {
    //获取ViewHolder回得到快速访问的TextView
    //和ImageView的。
    支架=(ViewHolder)convertView.getTag();
}

//与支架有效地绑定的数据。
holder.text.setText(的getItem(位置));
//更改图标取决于是sexmale变量是真还是假。
如果(getSex(的getItem(位置))==真){
    holder.icon.setImageBitmap(maleicon);
}
其他 {
    holder.icon.setImageBitmap(femaleicon);
}
返回convertView;
 

I have a dynamic ListView which uses an ArrayAdapter. When a name is selected from a spinner, the name together with an icon showing whether they are male or female gets added to the ListView.

Mostly everything is good (the name gets added to the list correctly, together with an icon). But the icon showing the sex gets added to the wrong item in the ListView. The name gets added to the bottom of the list, but the icon gets placed at the name at the top of the list. I don't know if it's the way I'm using ViewHolder but there is zero documentation on it in the Android website.

// Listview inflater
inflater = (LayoutInflater) (this).getSystemService(LAYOUT_INFLATER_SERVICE);

// List Array.
mAdapter = new ArrayAdapter<String>(this, R.layout.player_simple_list, 
                                                 R.id.label, mStrings) {

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

        Log.i("ANDY","View getView Called");
        // A ViewHolder keeps references to children views to 
        // avoid unneccessary calls to findViewById() on each row.
        ViewHolder holder;

        if (null == convertView) {
            Log.i("ANDY","Position not previously used, so inflating");
            convertView = inflater.inflate(R.layout.player_simple_list, null);
            // Creates a ViewHolder and store references to the
            // two children views we want to bind data to.
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.label);
            holder.icon = (ImageView) convertView.findViewById(R.id.icon);
            if (sexmale == true) {
                holder.icon.setImageBitmap(maleicon);
            }
            else {
                holder.icon.setImageBitmap(femaleicon);
            }
            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();

        }
        // Bind the data efficiently with the holder.
        holder.text.setText(getItem(position));
        // Change icon depending is the sexmale variable is true or false.
        Log.i("ANDY","getCount = "+mAdapter.getCount());
        return convertView;
    }
};
setListAdapter(mAdapter);

Update: ViewHolder is only meant to hold references to the component views inside the item layout. This helps to avoid the overhead of calling findViewById for rendering each component inside complex item layouts with multiple components(Like the TextView, and ImageView in this case).

I fixed it by using a routine (called getSex) to retrieve the sex data and setting all the view data including icons outside the if-else blocks.

The working code now looks like this:

if (null == convertView) {
    Log.i("ANDY","Position not previously used, so inflating");
    convertView = inflater.inflate(R.layout.player_simple_list, null);

    // Creates a ViewHolder and store references to the two children views
    // we want to bind data to.
    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.label);
    holder.icon = (ImageView) convertView.findViewById(R.id.icon);
    convertView.setTag(holder);
} else {
    // Get the ViewHolder back to get fast access to the TextView
    // and the ImageView.
    holder = (ViewHolder) convertView.getTag();
}

// Bind the data efficiently with the holder.
holder.text.setText(getItem(position));
// Change icon depending is the sexmale variable is true or false.
if (getSex (getItem(position)) == true)  {
    holder.icon.setImageBitmap(maleicon);
}
else {
    holder.icon.setImageBitmap(femaleicon);
}
return convertView;