Very simple error I'm sure, just having a mental block for some reason!
I have an object which contains an ArrayList of other objects. When I try to initialise the list in the constructor it does not seem to initialise and I get a nullpointer when I attempt to access the list within the code.
Order class variables:
private int covers;
private int table;
private ArrayList<MenuItem> items;
Here is the Order class:
public Order(int covers, int table) {
super();
this.covers = covers;
this.table = table;
this.items = new ArrayList<MenuItem>();
}
Here is the code within the MainActivity causing me problems:
order = new Order();
order.setCovers(2);
order.setTable(1);
order.addToOrder(new MenuItem("Item 1", 12.99));
Toast.makeText(getApplicationContext(), "order size: " + order.getItems().size(), Toast.LENGTH_SHORT).show();
I would expect the Toast to display "1". However when I ran debugger I noticed the order object ArrayList attribute was equal to null.
Any idea why? Thanks in advance!
EDIT: addToOrder method:
public void addToOrder(MenuItem m){
items.add(m);
}
You have failed to initialize items. Use
vorder = new Order(int1, int2);
instead of
vorder = new Order();
items is initialized inside
public Order(int covers, int table) {
}
not on the default constructor.
Related
I am using the second answer from this question How to filter a RecyclerView with a SearchView. I only changed the names of the ArrayLists so the code is the same. Problem is when I clear the main ArrayList, for some reason the secondary list also clears. Unless I am missing something obvious this shouldn't be happening. The code is attached below;
This is my constructor;
public CustomFoodAdapter(Context context, ArrayList<Foods> foodsArray) {
this.context = context;
this.foods = foodsArray;
this.foodsCopy = foodsArray;
}
And this is the method I call;
public void filter(String text) {
System.out.println("Foods copy: "+foodsCopy.size()); // Size is 54
foods.clear();
System.out.println("2 Foods copy: "+foodsCopy.size()); // Size is 0 (???)
if(text.isEmpty()){
foods.addAll(foodsCopy);
} else{
text = text.toLowerCase();
System.out.println("Length is: "+foodsCopy.size());
for(Foods item: foodsCopy){
System.out.println("Food name: "+item.foodName);
if(item.getFoodName().toLowerCase().contains(text)){
foods.add(item);
}
}
}
notifyDataSetChanged();
}
This is because you are copying the list in memory reference and not the content itself.
So in the CustomFoodAdapter constructor you would need to create a new array list with the foodsArray content in it.
It would be something like this:
public CustomFoodAdapter(Context context, ArrayList<Foods> foodsArray) {
this.context = context;
this.foods = new ArrayList<>(foodsArray);
this.foodsCopy = new ArrayList<>(foodsArray);
}
updated my code. My issue happens when i back out of the activity. Listview items are lost. I checked the Sqlite database and all items are saved, just not showing up again on listView when I reStart-Activity.
MainActivity
private ListView lst;
private CustomeAdapter cv;
private EditText nameEd, middleEd, lastEd;
private ArrayList<People> peopleArrayList;
private DataHelper myData;
peopleArrayList = new ArrayList<>();
OnCreate.....
public void addPerosn(View view) {
String myName = nameed.getText().toString();
String myMiddle = middleed.getText().toString();
String myLast = lasted.getText().toString();
boolean insert = myData.addData(myName, myMiddle, myLast);
if (insert == true) {
peopleArrayList.add(new People(myName, myMiddle, myLast));
cv = new CustomeAdapter(this, peopleArrayList);
lst.setAdapter(cv);
nameed.setText("");
middleed.setText("");
lasted.setText("");
} else {
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
}
}
}
My DataHelper method i want to call to Show All
public Cursor showData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return data;
}
Any suggestions are appreciated . Thanks
Make sure you have overridden getCount and it returns proper count.
#Override
public int getCount() {
return items.length;
}
Apart from above solution, I would recomment you to do it in proper way
a) Create a model/pojo class say Person which will have firstName,lastName and middleName
b) create a data set of Person, i.e list of person
c) create a method addPerson in adapter class, and call whenever you want to add new Person data into the list. addPerson method will also refresh the adapter by calling notifyDataSetChanged
d) In activity create adapter object only once, later on just use method of it say adapter.addPerson(person)
public void setSearch(ArrayList<Search> ListSearch){
search=ListSearch;
removeInActiveClasses(search);
notifyItemRangeChanged(0,search.size());
}
public void removeInActiveClasses(ArrayList<Search> data){
for(int i=0;i<data.size();i++){
boolean isActive=Boolean.parseBoolean(data.get(i).getActive());
System.out.println("The course at Not Removed "+search.get(i).getName()+" is set to "+search.get(i).getActive());
if(!isActive){
System.out.println("The course at Removed"+search.get(i).getName()+" is set to "+search.get(i).getActive());
search.remove(i);
}
}
}
A list is passed through as listSearch and it contains a list of courses, if the courses are set to active which is a string that either true or false, and parsed as a boolean, then the item should be removed. I am certain I did the parsing correctly so I am wondering what is going on here? How come it does not delete all the false courses?
You might wanna create another instance of ArrayList and set your search to that one because your are accessing and modifying your ArrayList at simultaneously.
Other notes:
Please use camelCase for your argument names. So instead of ListSearch, use searchList.
For your class variable, try adding m in front so you won't get confused. So instead of search, use mSearchList
Lastly, you are mixing some variables within one method. Try unifying them for better maintenance.
Here's the full code.
public void setSearchList(ArrayList<Search> searchList) {
mSearchList = removeInactiveClasses(searchList);
notifyDataSetChanged();
}
private ArrayList<Search> removeInactiveClasses(ArrayList<Search> data) {
ArrayList<Search> list = new ArrayList<>();
for (int i = 0; i < data.size(); i++){
boolean isActive = Boolean.parseBoolean(data.get(i).getActive());
if (isActive){
list.add(data.get(i));
}
}
return list;
}
I have an ArrayList, which is defined in one function, and gets called in another one. But when I add public ArrayList<String> list = new ArrayList<String>(); at the beginning, then run a function that adds items to that list and then try to call list in another function, it overwrites the previous set and just returns an empty list.
But when I just have public ArrayList<String> list; at the beginning, again add items in one function and then try to use list, it throws a NullPointerException.
I also tried having ArrayList<String> list = new ArrayList<String>(); in the onCreate method, but that's a NPE too.
So one function is just
public void setList() {
for(int x=0; x<=5;x++){
list.add(Integer.toString(x));
}
}
(the Integer.toString(x) is currently just for testing)
And the Other one is
public void setList() {
Log.d("Log",list.toString());
}
At the very beginning after public class MainActivity extends FragmentActivity {
I have tried
public ArrayList<String> list; //this throws a NPE
and
public ArrayList<String> list = new ArrayList<String>(); //this overwrites the variable each time it's called
How do I fix that?
Could the issue be that I change the displayed Fragment after the set method and before the get method is called?
Thank you very much
Use 1 list object at the top of the code and do not create new ones in the functions. It should look like this.
public static ArrayList<String> list = new ArrayList<String>();
// onCreate....
public void addElement() {
for(int x=0; x<=5;x++){
list.add(Integer.toString(x));
}
}
public void showElements() {
Log.d("Log",list.toString());
}
public class UnitListAdapter extends ArrayAdapter<Unit> {
private Context context;
private ArrayList<Unit> units;
private MeasurementType type;
private static HashMap<String, Double> unitValues;
public void setMeasurementType(MeasurementType measurementType) {
type = measurementType;
}
public void setUnitValues(HashMap<String, Double> newValues) {
unitValues.clear();
unitValues = newValues;
}
public void setUnits(ArrayList<Unit> newUnits) {
units = newUnits;
}
}
Above is the implementation of ArrayAdapter minus the getView() and getCount() methods. Now, in my activity I have this method:
public void updateUnitAdapter(ArrayList<Unit> units, final MeasurementType measurementType) {
//change the type
unitAdapter.setMeasurementType(measurementType);
//set the hashmap unit values
unitValues = new HashMap<String, Double>() {{
put(measurementType.getType(), DEFAULT_VALUE);
}};
//clear the current units for the previous measurement type
unitAdapter.clear();
//add the new units for the new measurement type
for(Unit u : units) {
unitAdapter.add(u);
}
//update the list view
unitAdapter.notifyDataSetChanged();
}
but when I step through in the debugger, it gets to the getView() method and when I check these variables, they are haven't changed to the new ones that I am setting them too, they stay the same...is there something I am not understanding about ArrayAdapter ?
ArrayAdapter has its own internal collection, which is modified when you call add() or clear(). In this case you are updating it, but (from your comments) it looks like you have also overriden getCount() and getView() to get those values from somewhere else (possibly the units member?).
If that's the case, you should update units intead of calling clear()/add().
Otherwise, remove the units field altogether and use getItem() to access the collection items.