遇到设置列表视图项目颜色的问题

发布于 2024-12-29 10:10:10 字数 3522 浏览 1 评论 0原文

我的列表中包含有两个文本视图和一个图像视图的项目。我使用 ArrayAdapter 来膨胀列表。除了单击时更改列表项颜色之外,一切正常。我的列表视图中有 22 个项目。主要是列表视图在屏幕上显示 10 个项目,并滚动其他项目。现在我的问题是,当我单击 0-9(初始 10 个项目)之间的单个项目时,项目会在单击时正确更改其颜色,但是当我滚动并单击时在位置大于 9 的项目(在最初的 10 个项目之后)上,我的活动崩溃了。我指的是 http://www.mail-archive.com/[email protected]/msg09740.html链接在for循环中编写代码。帮助我解决这个问题。任何建议或解决方案将受到高度赞赏。提前致谢。

 @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());
            }   
    }

I have list with items having two textview and one imageview.I inflate the list with ArrayAdapter.Everything is working fine except changing list item color on click.I have 22 items in my listview. Primarily listview displaying 10 items on the screen and get the other items on scroll.Now my problem is when I clicks on a single item between 0-9(initial 10 items) item changes their color properly on click, but when i scroll and clicks on an item having position greater then 9(after the initial 10 items) my activity crashes.I am referring http://www.mail-archive.com/[email protected]/msg09740.html link to write the code in for loop.Help me to get rid of this problem.Any suggestions or solutions will be highly appreciated.Thanx in advance.

 @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());
            }   
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

神经暖 2025-01-05 10:10:11

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

这是完美的运行代码:-

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); 
                        } 
                    }

            });

I am giving the answer to my own question.

Here's the perfect running code:-

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); 
                        } 
                    }

            });
伤感在游骋 2025-01-05 10:10:11

我成功使用的一个更干净(?)的解决方案是创建一个 LinearLayout 的扩展小部件(或用于列表项布局的任何根视图类型),它实现 可检查

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/> 

A cleaner(?) solution I've successfully used is to create an extension widget of LinearLayout (or whatever root view type you use for your listitem layout) that implements 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();
}

}

Then in your item layout 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/> 
淤浪 2025-01-05 10:10:10

将此代码用于 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
());
  } 
} 

我认为您的意图只是更改单击项目的背景颜色。为此,您不需要添加 for 循环。如果您的意图与我所说的相同,则仅在 for 循环的位置使用此代码。

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

Use this code for the for loop.

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
());
  } 
} 

I think your intention to only change the bacground color of clicked item. For that you not need to add for loop. if your intention is same as i said then use this code only at the place of for loop.

getListView().getChildAt(position).setBackgroundColor(Color.GREEN); 
鱼窥荷 2025-01-05 10:10:10

还有其他方法可以做。

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



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

There is other way to do.

First you need to add a selector xml e.g. 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"/>

and then set it as a background of your list view cell.

坏尐絯 2025-01-05 10:10:10

您可以这样尝试:

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;
    }
}

这会给您带来如下行为:

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

You can try like this:

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;
    }
}

This will give you behavior like:

  • Initially all items would be red colored.
  • if you click on 2nd item,then it will turn green(according to my code).
  • Now when you scroll and click on any other items,they will keep on turning green from red.
  • But if you click on "green" colored item,it will again turn red like it is unselected!
放我走吧 2025-01-05 10:10:10

执行类似的操作

你可以在 oncreate 之外

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;
            }
        });

you can do something like this

@ outside of on create

View prevView;

then in 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;
            }
        });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文