在android中没有用户交互的情况下更改特定列表项的textview颜色

时间:2015-09-03 11:09:25

标签: android listview

我有一个ArrayList<String>和一些数据。我将它与其他项目一起传递给我的Custom ArrayAdapter构造函数。在getView方法中,我使用listitems检查Arraylist<String>项目。

如果它们相同,那么我想更改Listview中textview的颜色。它会更改某些项目的颜色,但是当我滚动Listview时,它会更改不在ArrayList<String>传递的其他项目的颜色。

下面是我的构造函数和getView()方法的代码:

   public CustomMenuArrayAdapter(Context ctx,int res,String[] menuName,String[] menuDesc,String[] menuIngred,String[] menuPrice,List orderNames){
   super(ctx,res,menuName);
   this.ctx=ctx;
   this.menuName=menuName;
   this.menuDesc=menuDesc;
   this.menuIngred=menuIngred;
   this.menuPrice=menuPrice;
   this.orderNames=orderNames;
   this.inflaters=LayoutInflater.from(ctx); 
}     


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

    ViewHolder viewHold;
    View v=convertView;
    if(v==null){
        viewHold=new ViewHolder();
        v=inflaters.inflate(R.layout.category_details,parent,false);
       // viewHold.txtQtys=(TextView)v.findViewById(R.id.txtQty);
        viewHold.txtAdd=(TextView)v.findViewById(R.id.txtAdd);
        viewHold.txtPrices=(TextView)v.findViewById(R.id.txtPrices);
        viewHold.txtName=(TextView)v.findViewById(R.id.txtCatNameDetails);
        viewHold.txtDesc=(TextView)v.findViewById(R.id.txtCatDescDetails);
        viewHold.txtIngred=(TextView)v.findViewById(R.id.txtIngredientDetails);
       // viewHold.add=(ImageView)v.findViewById(R.id.imgPlus);
       // viewHold.sub=(ImageView)v.findViewById(R.id.imgMinus);
        v.setTag(viewHold);
       // viewHold.txtName.setTag(position);
    }else{
        viewHold=(ViewHolder)v.getTag();
    }

   if(orderNames.get(0)!=null || !orderNames.get(0).equals("")) {
           for(int k=0;k<orderNames.size();k++) {
               Log.e("k:----->"+k," menuN:"+menuName[position]+"<--->"+orderNames.get(k));
               if (orderNames.get(k).toString().equals(menuName[position])) {
                    TextView txt=(TextView)v.findViewById(R.id.txtCatNameDetails);
                    txt.setBackgroundColor(Color.LTGRAY);
                   break;
               }

               }
           }

    viewHold.txtName.setText(menuName[position]);
    viewHold.txtDesc.setText("Desc: "+menuDesc[position]);
    viewHold.txtIngred.setText("Ingred: "+menuIngred[position]);
    viewHold.txtPrices.setText("UGX : " + menuPrice[position]);

    return v;
}   

7 个答案:

答案 0 :(得分:1)

使用ViewHolder是一个很好的方法,但用下面的代码替换你的getView()方法,你会得到你想要的..........

public View getView(final int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
         convertView = inflaters.inflate(R.layout.category_details, parent, false);
            TextView txtAdd = (TextView) convertView.findViewById(R.id.txtAdd);
            TextView txtPrices = (TextView) convertView.findViewById(R.id.txtPrices);
            TextView txtName = (TextView) convertView.findViewById(R.id.txtCatNameDetails);
            TextView txtDesc = (TextView) convertView.findViewById(R.id.txtCatDescDetails);
            TextView txtIngred = (TextView) convertView.findViewById(R.id.txtIngredientDetails);

            if (orderNames.get(0) != null || !orderNames.get(0).equals(""))
            {
                for (int k = 0; k < orderNames.size(); k++)
                {
                    Log.e("k:----->" + k, " menuN:" + menuName[position] + "<--->" + orderNames.get(k));
                    if (orderNames.get(k).toString().equals(menuName[position]))
                    {
                        txtName.setBackgroundColor(Color.LTGRAY);
                    }
                    else
                    {
                        txtName.setBackgroundColor("default color");
                    }
                }
            }
            txtName.setText(menuName[position]);
            txtDesc.setText("Desc: " + menuDesc[position]);
            txtIngred.setText("Ingred: " + menuIngred[position]);
            txtPrices.setText("UGX : " + menuPrice[position]);
        }
        return convertView;
    }

答案 1 :(得分:1)

确保您的逻辑合理。例如,这看起来不对:

if (orderNames.get(0) != null || !orderNames.get(0).equals("")) {
    ....
}

首先检查你执行的是:

orderNames.get(0) != null

此检查的两个结果:

  1. TRUE orderNames.get(0)不是null ===&gt;由于你是ORing,所以甚至没有进行第二次检查。

  2. 错误orderNames.get(0)null ===&gt;由于您是ORing ===&gt;而执行了第二次检查这将在这里为您NullPointerException提供!(null).equals("")

  3. 这看起来更好:

    // Check if orderNames.get(0) is empty (note the use of `trim()`)
    if (orderNames.get(0) != null && !orderNames.get(0).trim().equals("")) {
        ....
    }
    

    更好:

    // Rejects `null`, ""(empty string) & "    "(strings that contain only whitespaces)
    if (!TextUtils.isEmpty(orderNames.get(0)) && !TextUtils.isEmpty(orderNames.get(0).trim)) {
        ....
    }
    

    但是,我不知道你用这张支票完成了什么。这仅确认列表中的第一项包含非空字符串。稍后,您将遍历整个列表,甚至不执行任何空字符串或空字符串检查。

    我不推荐这个,但试一试。如果它有效,找出原因:

    // Reset - in case this view was recycled
    viewHold.txtName.setBackgroundColor(Color.TRANSPARENT);
    
    if (!TextUtils.isEmpty(orderNames.get(0)) && !TextUtils.isEmpty(orderNames.get(0).trim)) {
        for(int k = 0; k < orderNames.size(); k++) {
            Log.e("k:----->" + k, " menuN: " + menuName[position] + "<--->" + orderNames.get(k));
    
            // Can possibly throw NPE
            // If `menuName[position]` is guaranteed to be non-null, you can reverse the check
            if (orderNames.get(k).toString().equals(menuName[position])) {
                viewHold.txtName.setBackgroundColor(Color.LTGRAY);
                break;
            }
        }
    }
    

    注意:您对ViewHolder模式的实现很好。

答案 2 :(得分:0)

这是因为您正在使用视图模式,这意味着您正在重复使用屏幕外的视图来查看屏幕上显示的视图。这意味着如果您不自行重置,则视图符号将显示其属性,例如颜色。所以在你的情况下你

TextView txt=(TextView)v.findViewById(R.id.txtCatNameDetails);
if (orderNames.get(k).toString().equals(menuName[position])) {
     txt.setBackgroundColor(Color.LTGRAY);
     break;
} else {
     txt.setBackgroundColor(/* default color */);
     break;
}

答案 3 :(得分:0)

那是因为你的代码错了。您没有正确使用ViewHolder模式。你的&#34;其他&#34;在getView中不应该存在。

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

ViewHolder viewHold;
View v=convertView;
if(v==null){
    viewHold=new ViewHolder();
    v=inflaters.inflate(R.layout.category_details,parent,false);
   // viewHold.txtQtys=(TextView)v.findViewById(R.id.txtQty);
    viewHold.txtAdd=(TextView)v.findViewById(R.id.txtAdd);
    viewHold.txtPrices=(TextView)v.findViewById(R.id.txtPrices);
    viewHold.txtName=(TextView)v.findViewById(R.id.txtCatNameDetails);
    viewHold.txtDesc=(TextView)v.findViewById(R.id.txtCatDescDetails);
    viewHold.txtIngred=(TextView)v.findViewById(R.id.txtIngredientDetails);
   // viewHold.add=(ImageView)v.findViewById(R.id.imgPlus);
   // viewHold.sub=(ImageView)v.findViewById(R.id.imgMinus);
    v.setTag(viewHold);
   // viewHold.txtName.setTag(position);
}
ViewHolder holder = (ViewHolder) v.getTag();
...
}   

答案 4 :(得分:0)

当您使用ViewHolder模式时,这意味着您正在重复使用视图,因此当您的ListView滚动时,它会更改其他项目的颜色,因为您正在重复使用您的视图。

您需要将这两种方法添加到CustomMenuArrayAdapter以使其正常工作。

@Override
public int getViewTypeCount() {
  return getCount();
}

@Override
public int getItemViewType(int position) {
  return position;
}

答案 5 :(得分:0)

让我假装您使用了viewHold.txtName.setBackgroundColor(Color.LTGRAY);

//comes below  viewHold=(ViewHolder)v.getTag();}
viewHold.txtName.setBackgroundColor(Color.Transparent);

现在展示你的爱

答案 6 :(得分:0)

删除支票v == null (convertView),每次都致电viewHold=new ViewHolder();。 我认为ListView回收是卡住的问题。