I have two List ArrayList which have some string values. Also, I have a ListView and an ArrayAdapter. The data given to the ArrayAdapter is coming from one of the 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.
I tried using listview.getChildAt(i).setBackgroundColor(Color.Blue) but it doesnt works. 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. 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
<?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
<?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).
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. 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
. I would add the elements like this: forexInstruments.add(getDefaultItem("USDGPY"));
, where getDefaultItem
is method that returns ListItem
with background set to 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.
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:
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.
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.
您需要通知适配器有关更改:
arrrayAdapter.notifyDataSetChanged();
I think you are trying to getItem of list when it is not yet completely set.Please check if below helps:
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" + "'",
while:
forexInstruments.get(0) = EURCAD ;
There is a difference of '
in both the strings so they wont be equal.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.