6

我想创建一个视图,我可以从列表视图中选择多个项目,并且并排更改所选列表项的颜色并将该项目保存到我的数组列表中。我的列表如下所示:

在此处输入图像描述

但是当我用来滚动它时..它显示我选择了另外 1 个项目,即使我没有像这样选择它:

在此处输入图像描述

但我希望只有那个列表项颜色应该改变我将点击的位置......

我将代码用作:

     private class ItemsAdapter extends ArrayAdapter<String> {
 List<String> items;
  Context context;
  private LayoutInflater inflater;
  public ItemsAdapter(Context context, List<String> part_array_list) {
     super( context, R.layout.part_list, R.id.label,part_array_list );

     inflater = LayoutInflater.from(context) ;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      TextView textView ; 
    String item = (String) this.getItem( position ); 

      if ( convertView == null ) {
        convertView = inflater.inflate(R.layout.part_list, null);

        // Find the child views.
        textView = (TextView) convertView.findViewById( R.id.label );


        // Optimization: Tag the row with it's child views, so we don't have to 
        // call findViewById() later when we reuse the row.
        convertView.setTag( new ListViewHolder(textView) );


      }
      // Reuse existing row view
      else {
        // Because we use a ViewHolder, we avoid having to call findViewById().
        ListViewHolder viewHolder = (ListViewHolder) convertView.getTag();

        textView = viewHolder.getTextView() ;

      }


      textView.setText( part_array_list.get(position) );      

      return convertView;


      }
      }
        /** Holds child views for one row. */
           private class ListViewHolder {

 private TextView textView ;
 public ListViewHolder() {}
 public ListViewHolder( TextView textView ) {

   this.textView = textView ;
 }

 public TextView getTextView() {
   return textView;
 }
 public void setTextView(TextView textView) {
   this.textView = textView;
 }    

}

在 OnCreate() 方法中,

         final ArrayAdapter<String> part_list_adapter=new ItemsAdapter(AssetSearch.this, part_array_list);
        //PartNumber_List.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    PartNumber_List.setAdapter(part_list_adapter);

    PartNumber_List.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position,
            long id) {
         ListViewHolder viewHolder = (ListViewHolder) v.getTag();
         viewHolder.getTextView().setBackgroundColor(R.color.result_image_border);

        String item=(String) part_list_adapter.getItem((int) id);
        });
4

7 回答 7

10

这里的问题是您正在为视图设置背景颜色,然后当您滚动时,由于使用convertView. 这正是你应该做的,所以做得很好。

但是,当然,这意味着列表项在不应该被选中时被选中。为了解决这个问题,您的getView()方法需要将背景颜色重置为其默认值。我不知道最初的颜色是什么,但我会假设它是透明的。所以你会说:

textView.setBackgroundColor(android.R.color.transparent);

因此,现在您将背景颜色设置为其默认值,但如果您从所选项目滚动离开,然后返回它,它将具有透明背景而不是所选背景。要解决此问题,请在您的适配器类中放置一个值ArrayListInteger当一个项目被点击并被onItemClick()触发时,将项目位置添加到该ArrayList. 例如,假设您有:

public ArrayList<Integer> selectedIds = new ArrayList<Integer>();

在您的适配器类中。然后,您的onItemClick方法将如下所示:

@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

     ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds;
     Integer pos = new Integer(position);
     if(selectedIds.contains(pos) {
         selectedIds.remove(pos);
     }
     else {
         selectedIds.add(pos);
     }

     parent.notifyDataChanged();
}

所以,最后,在你的getView()方法中,添加这一行:

textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
于 2012-04-11T05:47:35.513 回答
3

我也遇到过这个问题,发现是因为回收views。如果我记得正确设置,这将消除回收并解决问题,但这不是这里的最佳选择。

@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
于 2012-04-11T05:39:58.203 回答
1

跟踪 Activity 中 listView 中选择的项目。在适配器的 getView 中,检查位置是否等于列表视图中的选定位置和那里的视图的 setBackgroundColor。这将起作用。

于 2012-04-11T05:36:37.833 回答
1

无论您尝试在 itemClick 侦听器中使用 ConvertView 做什么,它都会反映在其他一些类中,以避免您需要为相应的视图持有者设置背景,我展示了一些对我来说很好的示例,

public View getView(final int position, View convertView, ViewGroup parent) {
         System.gc();
         final ViewHolder holder;

         if (convertView == null) {
             convertView = mInflater.inflate(R.layout.albumlist, null);
             holder = new ViewHolder();
             holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails);

             convertView.setTag(holder);
         }
         else {
             holder = (ViewHolder) convertView.getTag();
         }


         holder.albumName.setText(albumData[position][0]);

         holder.albumName.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 holder.albumName.setBackgroundColor(R.color.black);


             }});

         return convertView;
 }

     class ViewHolder {

         TextView albumName;


     }

样品 o/p 在此处输入图像描述

于 2012-04-11T07:53:07.767 回答
0

当您单击列表中的任何列表项时,您必须设置标志并检查此标志以确定是否在适配器的 getView() 方法中单击了该项目。

于 2012-04-11T05:44:37.797 回答
0

关于@JasonRobinson 给出的答案的更正:

if(selectedIds.contains(pos) {
         selectedIds.remove(pos); -> **selectedIds.remove(selectedIds.indexOf(pos));**
     }
     else {
         selectedIds.add(pos);
     }
于 2013-03-25T14:41:20.970 回答
0

Jason Robinson的解决方案(想法)很好,但是有一个错误!您不能通过它的值从 ArrayList 中删除项目!!!
方法 ArrayList.remove(int) 将项目的索引作为参数!
如果要使用,则需要找到要删除的索引项。例如:ArrayList<Integer>

private int getIndex(int value) {
    int index = -1;

    for(int i=0; i<selectedIds.size(); i++) {
        if(selectedIds.get(i)==value) {
            index = i;
            break;
        }
    }

    return index;
}

或者使用方法ArrayList.indexOf(Object)获取索引。

现在,如何从 FragmenList 或 ListActivity 获取对适配器的引用。只需使用类变量:

public class SimpleFragment extends ListFragment {
    private MyCustomAdapter mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mAdapter = new MyCustomAdapter(getActivity(), R.layout.row_layout);
        setListAdapter(mAdapter);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // now you have an access to your adapter through class variable mAdapter
    }
}
于 2013-07-17T13:02:37.763 回答