Android - 使用ListView问题

时间:2012-03-27 12:10:58

标签: java android listview

作为法国开发者,我为我的英语道歉。

所以,我的目标是为我的Android应用程序创建一个电话簿。这本电话簿由ListView组成。我用自定义适配器填充了ListView,允许用户在每行中选择一些TextView。 我认为一张图片胜过千言万语,所以这就是:

enter image description here

正如您所看到的,红色部分是我选择的TextView。 我必须面对的问题如下:

当我从一行中选择一个TextView时,下面4个位的行的TextView也会被选中!这是一个常见问题还是由于我的代码?

我在点击监听器上添加了一个日志,对于我点击的每个TextView,我只收到一个日志,所以我不认为问题来自我的工作。

例如,如果有些人不明白我所说的话;我在第二行选择带有drawableLeft图片的TextView。 logcat返回以下条目: “选择:1”(在我的代码中定义)。 如果我向下滚动ListView,我可以看到我的第二行(即我的TextView)是按预期选择的,但也是我的第6行,这根本不是预期的!

这是我用来着色或不用行的代码:

public View getView(final int position, View convertView, ViewGroup parent)
{
    selectedLocations.add(new Boolean(false));
    selectedAvailabilities.add(new Boolean(false));

    if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);

    final LinearLayout root = (LinearLayout) convertView.findViewById(R.id.phonebook_adapter_root);
    final ImageView photo = (ImageView) convertView.findViewById(R.id.phonebook_adapter_image);
    final TextView firstname = (TextView) convertView.findViewById(R.id.phonebook_adapter_firstname);
    final TextView lastname = (TextView) convertView.findViewById(R.id.phonebook_adapter_lastname);
    final TextView location = (TextView) convertView.findViewById(R.id.phonebook_adapter_location);
    final TextView availability = (TextView) convertView.findViewById(R.id.phonebook_adapter_availability);

    Bitmap mBitmap = null;
    try
    {
        mBitmap = Media.getBitmap(context.getContentResolver(), Uri.parse(relations.get(position).getPhoto()));
        photo.setImageBitmap(mBitmap);
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

    firstname.setText(relations.get(position).getFirstName());
    lastname.setText(relations.get(position).getLastName());

    DBStatus dbStatus = new DBStatus(KramerApplication.getInstance());
    Status status = dbStatus.getWithRelation(relations.get(position));
    dbStatus.close();

    if (status != null)
    {           
        location.setText( status.getLocation() );
        availability.setText( status.getAvailability() );

        if ( status.getDisplayedAvailability(2).equals("Busy") )
            availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0);
        else if ( status.getDisplayedAvailability(2).equals("Occupied") )
            availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0);
        else if ( status.getDisplayedAvailability(2).equals("Free") )
            availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_on, 0, 0, 0);
        else
            availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_off, 0, 0, 0);
    }

    root.setOnClickListener(new OnClickListener() {
        public void onClick(View v)
        {
            Intent intent = new Intent(context, ContactDetailsActivity.class);
            intent.putExtra("contact_id", relations.get(position).getId());
            context.startActivity(intent);
        }
    });

    location.setOnClickListener(new OnClickListener() {
        public void onClick(View v)
        {
            if (selectedLocations.get(position).booleanValue())
            {
                selectedLocations.set(position, new Boolean(false));
                location.setBackgroundColor(Color.TRANSPARENT);
            }
            else
            {
                selectedLocations.set(position, new Boolean(true));
                location.setBackgroundColor(Color.RED);
            }
        }
    });
    availability.setOnClickListener(new OnClickListener() {
        public void onClick(View v)
        {
            if (selectedAvailabilities.get(position).booleanValue())
            {
                selectedAvailabilities.set(position, new Boolean(false));
                availability.setBackgroundColor(Color.TRANSPARENT);
            }
            else
            {
                selectedAvailabilities.set(position, new Boolean(true));
                availability.setBackgroundColor(Color.RED);
            }
        }
    });

    return convertView;
}

ArrayLists“selectedAvailabilities”和“selectedLocations”已在构造函数中正确初始化,并在我在另一个活动中使用它们时执行它们的工作(只读)。

我希望你能帮助我。

问候。

#################################解决方案

如果有人正在寻找解决方案,那么就是这样。非常感谢user936414!。

替换(第6行):

if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);

人:

convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);

在:

return convertView;

添加:

if (selectedAvailabilities.get(position).booleanValue())
{
    availability.setBackgroundColor(Color.RED);
}
if (selectedLocations.get(position).booleanValue())
{
    location.setBackgroundColor(Color.RED);
}

1 个答案:

答案 0 :(得分:4)

此行为的原因是使用convertview。要解决此问题,请使用HashSet并将所有位置放在HashSet中。在getView中,检查包含TextView的Hashset和setSelected。希望这会有所帮助。

添加

 if (selectedLocations.get(position).booleanValue())
 {
           location.setBackgroundColor(Color.RED);
 }
 else
 {

            location.setBackgroundColor(Color.TRANSPARENT);
 }

在onClickListener之外也确保convertView不会影响您的需求。