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

2023-09-12 23:53:08 作者:太阳花

我有一个动态的的ListView ,它使用了 ArrayAdapter 。当一个名字是从一个微调选择,一起名称与图标显示无论是男性还是女性被添加到的ListView

晴一切都是美好的(名字被用一个图标添加到列表中正确的,在一起)。但显示了性行为的图标被添加到了的ListView 错误的项目。的名称被添加到列表的底部,但图标被放置在名称,在该列表的顶部。我不知道这是否是我用 ViewHolder 的方式,但有它的零文档中的 Android的网站。

  //列表视图气筒
充气=(LayoutInflater)(本).getSystemService(LAYOUT_INFLATER_SERVICE);

//列表阵列。
mAdapter =新的ArrayAdapter<字符串>(这一点,R.layout.player_simple_list,
                                                 R.id.label,mStrings){

    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){

        Log.i(安迪,查看getView名为);
        //一个ViewHolder不断提及孩子意见
        //避免不必要的调用findViewById()每一行上。
        ViewHolder持有人;

        如果(空== 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);
            如果(sexmale ==真){
                holder.icon.setImageBitmap(maleicon);
            }
            其他 {
                holder.icon.setImageBitmap(femaleicon);
            }
            convertView.setTag(保持器);
        } 其他 {
            //获取ViewHolder回得到快速访问的TextView
            //和ImageView的。
            支架=(ViewHolder)convertView.getTag();

        }
        //与支架有效地绑定的数据。
        holder.text.setText(的getItem(位置));
        //更改图标取决于是sexmale变量是真还是假。
        Log.i(安迪,getCount将=+ mAdapter.getCount());
        返回convertView;
    }
};
setListAdapter(mAdapter);
 

解决方案

更新: 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;
 

Listview列表视图 基本属性和简单适配器ArrayAdapter 一

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;