简体   繁体   English

如果找到MATCH,则更改ListView项目的背景颜色(Android ListView)

[英]Change background color of ListView Items if MATCH found (Android ListView)

I have two List ArrayList which have some string values. 我有两个具有一些字符串值的列表ArrayList。 Also, I have a ListView and an ArrayAdapter. 另外,我有一个ListView和一个ArrayAdapter。 The data given to the ArrayAdapter is coming from one of the ArrayList. 提供给ArrayAdapter的数据来自ArrayList之一。


What I want to achive is : Compare both the arrayLists and if two elements present in the arrayLists are same, Then when the ListView is generated, the background for the listView item for which a match was found should be of different color. 我要实现的是:比较arrayLists和arrayLists中存在的两个元素是否相同,然后在生成ListView时,找到匹配项的listView项的背景应为不同的颜色。


I tried using listview.getChildAt(i).setBackgroundColor(Color.Blue) but it doesnt works. 我尝试使用listview.getChildAt(i).setBackgroundColor(Color.Blue)但它不起作用。 It is giving me as java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setBackgroundColor(int)' on a null object reference on the same line. 它给我的方式是java.lang.NullPointerException:尝试在同一行的空对象引用调用虚拟方法'void android.view.View.setBackgroundColor(int)' If there is any better way to do this then post it in your answers. 如果有更好的方法可以将其发布在您的答案中。

 private List<String> forexInstruments;
 private ListView forexListView;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

String[]  temp = new String[]{
                "'" + "EURCAD" + "'",
                "'" + "USDGPY" + "'",
                "'" + "AUDUSD" + "'",
                "'" + "USDCHF" + "'",
                "'" + "EURGPY" + "'",
                "'" + "6B 03-16" + "'",
                "'" + "6E 03-16" + "'",
                "'" + "CL 03-16" + "'",
                "'" + "ZB 09-16" + "'"    
        };
    //1st Array List
    selectedGlobalInstruments = new ArrayList<>(Arrays.asList(temp));

    //2nd Array List
    forexInstruments = new ArrayList<>();
    forexInstruments.add("EURCAD");
    forexInstruments.add("USDGPY");
    forexInstruments.add("AUDUSD");
    forexInstruments.add("EURGBP");
    forexInstruments.add("USDJPY");
    forexInstruments.add("GBPUSD");
    forexInstruments.add("EURGPY");
    forexInstruments.add("USDCHF");


    forexListView = (ListView) findViewById(R.id.listView);
    final ArrayAdapter arrayAdapter = new    ArrayAdapter(this,R.layout.list_item_layout,R.id.list_item_instrument_textview,forexInstruments);
    forexListView.setAdapter(arrayAdapter);

    //Comparing both the ArrayLists. If two elements ar eqaul then change background color
    for(int j=0; j< selectedGlobalInstruments.size(); j++) {
        String tempA = selectedGlobalInstruments.get(j);
        Log.v("Selcted",selectedGlobalInstruments.get(j));
        for(int i=0; i < forexListView.getCount(); i++)
        {
            String instrumentList = "'" + forexListView.getItemAtPosition(i).toString()+ "'";
            Log.v("forexListview",instrumentList);
            if (tempA.equals(instrumentList)) {
                Log.v("Satisfied",instrumentList);
                forexListView.getChildAt(i).setBackgroundColor(Color.BLUE);
                arrayAdapter.notifyDataSetChanged();
            }
        }
    }

list_item_layout.xml list_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item_instrument_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed"
android:textSize="18sp"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:textColor="#000000"
android:textStyle="bold"
android:layout_marginRight="10dp">
</TextView>

activity_main.xml activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.shubhamhpcs.listviesttes.MainActivity">

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/listView"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
</RelativeLayout>

In my opinion, an Activity shouldn't take care how an item from ListView is displayed, letting this job for an adapter (you're doing this in onCreate without having the rows for ListView created, resulting in a crash). 在我看来, Activity不应该关心如何显示ListView的项目,而让此工作用于适配器(您在onCreate执行此操作而没有创建ListView的行,导致崩溃)。
So what I would do is to create a class that has 2 fields: String value where you have your actual data to be displayed and a boolean hasBackground that indicates if that item should be displayed with a custom background or not. 因此,我要做的是创建一个具有2个字段的类: String value ,您可以在其中显示实际数据,以及一个boolean hasBackground ,该boolean hasBackground指示是否应使用自定义背景显示该项目。 That class should look like this: 该类应如下所示:

public class ListItem {
  public String value;
  public boolean hasBackground = false;

  public ListItem(String value, boolean background) {
    this.value = value;
    this.hasBackground = background;
  }
}

Then I would make the forexInstruments to have elements of type ListItem . 然后,我要使forexInstruments具有类型ListItem元素。 I would add the elements like this: forexInstruments.add(getDefaultItem("USDGPY")); 我将添加如下元素: forexInstruments.add(getDefaultItem("USDGPY")); , where getDefaultItem is method that returns ListItem with background set to false . ,其中getDefaultItem是返回ListItem且背景设置为false

private ListItem getDefaultItem(String value) {
    return new ListItem(value, false);
} 

After the list is initialised it have to be updated, so I created a method to find the common elements between those 2 lists, setting the hasBackground field to true for those elements. 初始化列表后,必须对其进行更新,因此我创建了一种方法来查找这两个列表之间的公共元素, hasBackground这些元素的hasBackground字段设置为true

private void updateCommonElements() {
    for (int j = 0; j < selectedGlobalInstruments.size(); j++) {
      for (int i = 0; i < forexInstruments.size(); i++) {
        String instrumentList = "'" + forexInstruments.get(i).value + "'";
        if (selectedGlobalInstruments.get(j).equals(instrumentList)) {
          forexInstruments.get(i).hasBackground = true;
        }
      }
    }
}

In the end, the onCreate would look like this: 最后, onCreate将如下所示:

forexInstruments = new ArrayList<>();
forexInstruments.add(getDefaultItem("USDGPY"));
forexInstruments.add(getDefaultItem("AUDUSD"));
forexInstruments.add(getDefaultItem("EURGBP"));
forexInstruments.add(getDefaultItem("USDJPY"));
forexInstruments.add(getDefaultItem("GBPUSD"));
forexInstruments.add(getDefaultItem("EURGPY"));
forexInstruments.add(getDefaultItem("USDCHF"));

updateCommonElements();

forexListView = (ListView) findViewById(R.id.listView);
MyAdapter adapter = new MyAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1);
adapter.addAll(forexInstruments);
forexListView.setAdapter(adapter);

where MyAdapter is a class extending ArrayAdapter , being responsible for colouring the background of a row or not. 其中MyAdapter是扩展ArrayAdapter的类,负责为行的背景着色。

public class MyAdapter extends ArrayAdapter<ListItem> {
  int res = 0;
  int textRes = 0;

  public MyAdapter(Context context, int resource, int textViewResourceId) {
    super(context, resource, textViewResourceId);
    res = resource;
    textRes = textViewResourceId;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
      convertView = LayoutInflater.from(parent.getContext()).inflate(res, parent, false);
    }
    ListItem item = getItem(position);
    if (item.hasBackground) {
      convertView.setBackgroundColor(Color.BLUE);
    } else {
      convertView.setBackgroundColor(Color.TRANSPARENT);
    }
    TextView textView = (TextView) convertView.findViewById(textRes);
    textView.setText(item.value);
    return convertView;
  }
}

And this is the final result in my simulator: 这是我模拟器中的最终结果: 屏幕截图

Note: I used some Android default layouts, but they can be changed to your layouts in a few seconds. 注意:我使用了一些Android默认布局,但是可以在几秒钟内将其更改为您的布局。

您需要通知适配器有关更改:

arrrayAdapter.notifyDataSetChanged();

I think you are trying to getItem of list when it is not yet completely set.Please check if below helps: 我认为您正在尝试尚未完全设置列表的getItem。请检查以下帮助:

ArrayAdapter arrayAdapter =null;
String[]  temp = new String[]{
            "'" + "EURCAD" + "'",
            "'" + "USDGPY" + "'",
            "'" + "AUDUSD" + "'",
            "'" + "USDCHF" + "'",
            "'" + "EURGPY" + "'",
            "'" + "6B 03-16" + "'",
            "'" + "6E 03-16" + "'",
            "'" + "CL 03-16" + "'",
            "'" + "ZB 09-16" + "'"    
    };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

init();


forexInstruments.add("EURCAD");
forexInstruments.add("USDGPY");
forexInstruments.add("AUDUSD");
forexInstruments.add("EURGBP");
forexInstruments.add("USDJPY");
forexInstruments.add("GBPUSD");
forexInstruments.add("EURGPY");
forexInstruments.add("USDCHF");

arrayAdapter.notifyDataSetChanged();

//Comparing both the ArrayLists. If two elements ar eqaul then change background color
checkSameItems();

}     

private void init(){
    //1st Array List
    selectedGlobalInstruments = new ArrayList<>(Arrays.asList(temp));

    //2nd Array List
    forexInstruments = new ArrayList<>();
    forexListView = (ListView) findViewById(R.id.listView);
    arrayAdapter = new    ArrayAdapter(this,R.layout.list_item_layout,R.id.list_item_instrument_textview,forexInstruments);
    forexListView.setAdapter(arrayAdapter);

}

private void checkSameTimes(){
     for(int j=0; j< selectedGlobalInstruments.size(); j++) {
    String tempA = selectedGlobalInstruments.get(j);
    Log.v("Selcted",selectedGlobalInstruments.get(j));
    for(int i=0; i < forexListView.getCount(); i++)
    {
        String instrumentList = "'" + forexListView.getItemAtPosition(i).toString()+ "'";
        Log.v("forexListview",instrumentList);
        if (tempA.equals(instrumentList)) {
            Log.v("Satisfied",instrumentList);
            forexListView.getChildAt(i).setBackgroundColor(Color.BLUE);
            arrayAdapter.notifyDataSetChanged();
        }
    }
 }
}

I think that your strings are both different, they wont be ever equal. 我认为您的琴弦都不同,它们将永远不相等。 Since your 自从你

selectedGlobalInstruments.get(0) = 'EURCAD';

which you are initializing as : "'" + "EURCAD" + "'", 您要初始化为: "'" + "EURCAD" + "'",

while: 而:

forexInstruments.get(0) = EURCAD ;

There is a difference of ' in both the strings so they wont be equal. 两个字符串中都有一个'的区别,因此它们将不相等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM