在列表视图项上设置颜色时出现问题

时间:2012-01-27 09:16:42

标签: android android-listview android-adapter

我有列表,其中包含两个textview和一个imageview。我使用ArrayAdapter给列表充气。除了在点击时更改列表项颜色外,一切正常。我的列表视图中有22个项目。主要是listview在屏幕上显示10个项目,并在滚动时获取其他项目。现在我的问题是当我点击0-9(最初的10个项目)之间的单项时,项目在点击时正确地改变了颜色,但是当我滚动并点击时对于位置大于9的项目(在最初的10个项目之后),我的活动崩溃了。我在http://www.mail-archive.com/android-developers@googlegroups.com/msg09740.html链接中编写for loop中的代码。帮助我摆脱这个问题。任何建议或者解决方案将受到高度赞赏。提前提交。

 @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        //  requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); // to hide the virtual keyboard
            setContentView(R.layout.defect_pic_listview);

            try{

                adapter = new MyArrayAdapter(this,makeList());
                setListAdapter(adapter);
                adapter.notifyDataSetChanged();
                getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                getListView().setOnItemClickListener(new OnItemClickListener() {

                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
                        //   Toast.makeText(getApplicationContext(), "Item "+position+" is clicked",
                        //            Toast.LENGTH_SHORT).show();

                             System.out.println("position"+position);
                                int first = getListView().getFirstVisiblePosition();
                                System.out.println("first="+first);
                                int last = getListView().getLastVisiblePosition();
                                System.out.println("last="+last);
                                int total = last - first;
                                System.out.println("total="+total);
                                if(getListView().isItemChecked(position)){
                                    for(int i = 0 ; i <= last ; i++){
                                        System.out.println("i="+i);
                                        if(first+i == position){
                                            getListView().getChildAt(i).setBackgroundColor(Color.GREEN);
                                            System.out.println("l1="+getListView());
                                    //      l.getItemAtPosition(i);
                                    //      System.out.println("l position"+l);
                                        }
                                        else{
                                            getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
                                            System.out.println("l2="+getListView());
                                        }
                                    }
                                }
                                else{
                                    getListView().getChildAt(position - first).setBackgroundColor(Color.TRANSPARENT); 
                                }
                            }
                    });
            }
            catch(Exception e){
                Log.d("error",e.getMessage());
            }   
    }

6 个答案:

答案 0 :(得分:0)

将此代码用于for循环。

if(getListView().isItemChecked(position))
{                                     
   for(int i = 0 ; i < total ; i++)
  {                                        
    System.out.println("i="+i); 
     if(first+i ==   position)
     { 
         getListView().getChildAt(i).setBackgroundColor(Color.GREEN); 
          System.out.println("l1="+getListView());
                                     //      l.getItemAtPosition(i); 
                                    //      System.out.println("l position"+l);
      }
      else
      {  
       getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
       System.out.println("l2="+getListView
());
  } 
} 

我认为您打算只更改点击项目的bacground颜色。为此,您不需要添加for循环。如果您的意图与我所说的相同,那么只在for循环的地方使用此代码。

getListView().getChildAt(position).setBackgroundColor(Color.GREEN); 

答案 1 :(得分:0)

还有其他办法。

首先你需要添加一个选择器xml,例如listviewitem_bg.xml

  

<item android:drawable="@drawable/listview_normal" android:state_enabled="true" android:state_pressed="false"/>
<item android:drawable="@drawable/listview_press" android:state_enabled="true" android:state_pressed="true"/>
     

然后将其设置为列表视图单元格的背景。

答案 2 :(得分:0)

您可以尝试这样:

public class CustomAdapter extends ArrayAdapter<String> {

    String[] array;
    Context mContext;
    LayoutInflater mInflater;
    int[] itemStates;

    public CustomAdapter(Context context, int textViewResourceId,
            String[] objects)
    {
        super(context, textViewResourceId, objects);
        array=objects;
        mContext=context;
        mInflater = LayoutInflater.from(context);
        //save all buttons state as 0(not clicked) initially
        itemStates=new int[objects.length];
        for(int i=0;i<objects.length;i++)
        {
             itemStates[i]=0;
        }  
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {       
        final ViewHolder holder;

        if(convertView==null)
        {
                 convertView = mInflater.inflate(R.layout.custom_listitem, null);
                 holder = new ViewHolder();

                 holder.text=(TextView)convertView.findViewById(R.id.text);
                 holder.layout=(LinearLayout)convertView.findViewById(R.id.linear_layout); // outer most linear layout iin custom_listitem xml
                 convertView.setTag(holder);
        }
        else
                holder=(ViewHolder)convertView.getTag();

        holder.text.setText(array[position]);

        if(itemStates[position]==0)
        {
            holder.layout.setBackgroundResource(R.drawable.red_gradient);  // item is not clicked/selected yet  
        }
        else
        {            
            holder.button.setBackgroundResource(R.drawable.green_gradient);  // item is clicked/selected so change its color        
        }       

        final int pos=position;
        holder.layout.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                itemStates[pos]=1;               
                holder.button.setBackgroundResource(R.drawable.green_gradient);                
            }
        });

        return convertView;
    }

    static class ViewHolder
    {
        TextView text;
        LinearLayout layout;
    }
}

这会给你以下行为:

  • 最初所有项目都是红色的。
  • 如果您点击第二项,那么它将变为绿色(根据我的代码)。
  • 现在当您滚动并点击任何其他项目时,它们将继续从红色变为绿色。
  • 但如果点击“绿色”彩色项目,它会再次变为红色,就像它未被选中一样!

答案 3 :(得分:0)

你可以做这样的事情

@在创建之外

View prevView;

然后在oncreate

lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int arg2,
                    long arg3) {
                if (prevView != null) {
                    prevView.setBackgroundColor(Color.TRANSPARENT);
                }
                view.setBackgroundColor(Color.RED);
                prevView = view;
            }
        });

答案 4 :(得分:0)

我正在回答我自己的问题。

这是完美的运行代码: -

getListView().setOnItemClickListener(new OnItemClickListener() {

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


            //   Toast.makeText(getApplicationContext(), "Item "+position+" is clicked",
                //            Toast.LENGTH_SHORT).show();

                        System.out.println("position="+position);
                        int first = getListView().getFirstVisiblePosition();
                        System.out.println("first="+first);
                        int last = getListView().getLastVisiblePosition();
                        System.out.println("last="+last);
                        int total = last - first;
                        System.out.println("total="+total);
                        if(getListView().isItemChecked(position)){
                            for(int i = first ; i <= last ; i++){
                                System.out.println("i="+i);
                                if(i == position){
                                    Log.w("TAG", "I am in If block");
                                    getListView().getChildAt(i-first).setBackgroundColor(Color.GREEN);
                                    System.out.println("l1="+getListView());
                            //      l.getItemAtPosition(i);
                            //      System.out.println("l position"+l);
                                }
                                else{

                                    getListView().getChildAt(i-first).setBackgroundColor(Color.TRANSPARENT);
                                    System.out.println("l2="+getListView());
                                }
                            }
                        }
                        else{
                            getListView().getChildAt(position).setBackgroundColor(Color.TRANSPARENT); 
                        } 
                    }

            });

答案 5 :(得分:0)

我成功使用的一个清洁(?)解决方案是创建一个LinearLayout扩展小部件(或用于listitem布局的任何根视图类型),它实现Checkable

public class CheckableLinearLayout extends LinearLayout implements Checkable {

boolean checked = false;

public CheckableLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CheckableLinearLayout(Context context) {
    super(context);
}

@Override
public void setChecked(boolean checked) {

    this.checked = checked;
    updateView();


}

/* (non-Javadoc)
 * @see android.widget.Checkable#isChecked()
 */
@Override
public boolean isChecked() {
    return this.checked;
}

/* (non-Javadoc)
 * @see android.widget.Checkable#toggle()
 */
@Override
public void toggle() {
    this.checked=!this.checked;
    updateView();

}

private void updateView() {
    if (this.checked) {
                            //Change to Whatever your checked color should be, maybe expose this as attribute so i't can be changed from xml attribute
             setBackgroundResource(R.color.default_background_color);
    } else {
        setBackgroundDrawable(null);
    }
    invalidate();
}

}

然后在你的项目布局xml:

<my.app.widgets.CheckableLinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

..any views for your listitem

<my.app.widgets.CheckableLinearLayout/>