I'm getting myself in a muddle with an ArrayAdapter I'm trying to put together. I've got a constructor, Person, which is used to put together people to go in a list. I'm then putting together an ArrayList of type Person to make a readable list.
I then put together an ArrayAdapter so that the list can be seen in a ListView, but I'm constantly getting "Cannot resolve constructor" with my code.
I've tried countless possible solutions on this site including trying to use getActivity() or this in place of PeopleActivity.this, but I just cannot get my code to compile. I've also tried referencing my constructor class in the ArrayAdapter, but that just gives me an error that it's not an enclosing class.
Person.class (constructor)
import android.text.Editable;
public class Person {
public Person Person;
private Editable personName;
public Person(Editable a) {
personName = a;
}
public void setName(Editable personName){
this.personName = personName;
}
public Editable getName() {
return personName;
}
}
PeopleActivity - populateListView
ArrayList<Person> peoplelistv = new ArrayList<Person>();
...
private void populateListView() {
ListView list = (ListView) findViewById(R.id.peopleListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PeopleActivity.this, android.R.layout.simple_list_item_1, peoplelistv);
list.setAdapter(adapter);
}
Any ideas folks?
Thanks
You are declaring the ArrayAdapter as ArrayAdapter<String>. However, the third parameter that you are passing to the constructor is neither a String[] nor a List<String>. If you are trying to wrap an ArrayList<Person> in an ArrayAdapter, it needs to be an ArrayAdapter<Person>, not ArrayAdapter<String>.
Related
I was making a food ordering application where I got stuck. I am calling the constructor of my class. Then, after assignment, this.listData my ArrayList is being reported redundant.
public class CartAdapter extends RecyclerView.Adapter<CartViewHolder> {
private List<Order> listData = new ArrayList<>();
private Context context;
public CartAdapter(List<Order> listData, Context context) {
this.listData = listData;
this.context = context;
}
}
Probably your IDE gives you the message that the following initialisation is redundant, not the field itself.
private List<Order> listData = new ArrayList<>();
The idea is that you have only one constructor, and this constructor expects all the time a List<Order>. This means that each time you make an instance of the class, you will be able to use the only constructor you provided, in which the field listData will have the value of the first parameter of the only constructor, so there is no need to initialize the field like that. This is why you get the "redundant initialisation" warning.
If you want to have a way of initialising the listData as an empty ArrayList, then you can provide an constructor where you don't handle the listData field. Otherwise, declaring private List<Order> listData; will do "the trick".
I am trying to add an object of class Track to my ArrayList of Track, playlist.
import java.util.ArrayList;
public class PlayList {
private String playList;
private ArrayList <Track> myTracks;
//constructors
public PlayList(String name) {
this.playList = name;
}
public PlayList(String name, ArrayList<Track> tracks) {
this.playList = name;
this.myTracks = tracks;
}
public addTrack(Track track){
myTracks.add(0,track)
}
}
But both my constructor and addTrack method fails, showing java.lang.NullPointerException
Where am I going wrong?
You never get an exception in your constructor. There is no chance at all.
And the reason for add method is you are using myTracks.add(0,track) and you never initialize your list
private List<Track> myTracks = new ArrayList<Track>();
You need to initialize the ArrayList and code to the interface.
Use : private List<Track> myTracks = new ArrayList<>(); (for java versions below java -7, use new ArrayList<Track>();)
I think your constructor fails because you try to initialize object from playList like this :-
playList myList = new playList();
This will give you error because there is no defualt constructor and it is not created by default (The default constructor is automatically generated unless you define another constructor)
If you didn't create your playList object like this there is no way you got an exception in the constructor
And the reason for addmethod error is you initialized your list
You have to do this :-
private List<Track> myTracks = new ArrayList<Track>();
You are getting "NullPointerException" in the Arraylist because you have not initialized it first. You can add items in list only after initializing it first.
So write like this instead and try -
private List<Track> myTracks = new ArrayList<Track>();
As far as the constructor is concerned i think there you didnt give the required parameters. When you are calling the constructor of PlayList class you need to pass the correct values as parameters which you defined(2 Constructors in this case). if you don't then it will throw an error because there is no default(no argument) constructor. So try like this -
PlayList myList=new PlayList("//give name","//ArrayList name which contains the tracks")
For my AP CompSci class, we're making a "Contacts" program to simulate using a virtual phonebook. The main class, Contacts is as follows.
public class Contacts extends ArrayList<Contact>
{
private ArrayList<Contact> contacts = new ArrayList<Contact>();
#Override
public boolean add(Contact c)
{
contacts.add(c);
Collections.sort(contacts);
return true;
}
public ArrayList<Contact> search(String name)
{
ArrayList<Contact> temp = new ArrayList<Contact>();
for(int i = 0; i<=contacts.size(); i++)
{
if(contacts.get(i).getName().equals(name))
{
temp.add(new Contact(name));
}
}
return temp;
}
}
As you can see, it extends ArrayList<Contact>. Contact is a simple object, composed of a String name and a 7-integer int num. The problem lies in the class ContactsFactory, where I loop through a text file to create a huge ArrayList of names.
public class ContactsFactory {
public static Contacts getContacts() throws FileNotFoundException {
String path = System.getProperty("user.dir");
Scanner s = new Scanner(new File(path + "\\src\\names.txt"));
Contacts contacts = new Contacts();
do {
contacts.add(new Contact(s.next()));
} while (s.hasNext());
s.close();
//print size to see anything added. It returns 0.
System.out.println(contacts.size());
return contacts;
}
}
However, when I implement the add() method for each name, not only does it seem not to add anything, but it returns no error. Even more interesting is that, as I found out when I put a print statement after every iteration, s.next() is no empty String. But the String(which experiences no issues being transferred from names.txt) is not added to contacts, and as a result, the ArrayList ends up empty with a size() of 0.
I think the error might be in the overridden Contacts.add() method, but I haven't been able to figure anything out. Can someone help me out? Thanks in advance.
I'm wondering why you extend ArrayList and additionally keep another copy of an ArrayList around. Besides the overwritten add (and size from azurefrog's answer), an ArrayList as well as the List interface offers a bunch of other methods - instead of overwriting all of them and delegating to the internal list, I would just rely on those methods and add the functionality I need:
public class Contacts extends ArrayList<Contact>
{
#Override
public boolean add(Contact c)
{
boolean result = super.add(c);
Collections.sort(this);
return result;
}
public ArrayList<Contact> search(String name)
{
// ...
}
}
By that you have a full-blown ArrayList and can extend it with what you need.
The other option is, to just kick out extends and just go for your own implementation of Contacts, utilizing the internal List as storage and not exposing it directly.
I think there is something wrong with your design.
I don't think you should extend ArrayList.
Because when you do it, your class IS an ArrayList, and also, you created an ArrayList object inside your class.
The thing is, when you called size, original ArrayList's size is being returned. Since you added the element to your ArrayList, the original is still empty.
You should use either delegation or inheritance, in this case you are mixing it both up.
Either implement java.util.List<Contact> (instead of extending ArrayList) and delegate every method call to the delegate (the class variable contacts)
OR
Remove the class variable contacts and use super.add() in your add method (instead of contacts.add()) and this instead of every other reference on contacts
I'm not sure how you read your file, but I seem to do just fine. In order to access the size of the contacts object in your factory, you need to call the 'size' method on the internal ArrayList instance variable, as opposed to calling on the 'contacts' object itself. In order to properly apply the 'size' method, it maybe that you need to override this method ('size') too.
Other than that, adding and retrieval seems fine. Check out the console output as well!
public class Contacts extends ArrayList<Contact>
{
private List<Contact> contacts = new ArrayList<Contact>();
#Override
public boolean add(Contact c)
{
contacts.add(c);
//Collections.sort(contacts);
return true;
}
#Override
public String toString()
{
return contacts.toString();
}
public List<Contact> getMyList()
{
return this.contacts;
}
public static void main(String[] args)
{
Contacts test=ContactsFactory.getContacts();
System.out.println(test.toString());
}
}
class ContactsFactory {
public static Contacts getContacts() {
String[] names={"A","B","C","D"};
int i=0;
Contacts contacts = new Contacts();
do {
System.out.println("Adding: "+names[i]);
contacts.add(new Contact(names[i]));
i++;
} while (i<names.length);
//print size to see anything added. It returns 0.
System.out.println(contacts.getMyList().size());
return contacts;
}
}
class Contact
{
String name;
#Override
public String toString()
{
return "Contact: "+this.name;
}
public Contact(String val)
{
this.name=val;
}
}
Output:
Adding: A
Adding: B
Adding: C
Adding: D
4
[Contact: A, Contact: B, Contact: C, Contact: D]
I use Sugar ORM for Android Development via Android Studio.
But I think I have a quite similar question.
How can I display one/multiple result queries as String or int?
My entity looks like this:
public class PersonsDatabase extends SugarRecord<PersonsSelection>{
String adultText, childText;
int adultCount, childCount;
public PersonsDatabase()
{
}
public PersonsDatabase(String adultText, String childText, int adultCount, int childCount)
{
this.adultText = adultText;
this.childText = childText;
this.adultCount = adultCount;
this.childCount = childCount;
this.save();
}
}
It saves correctly. But when I want to display like this:
public class PersonsSelection extends Activity {
ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_persons_selection);
PersonsDatabase personsDatabase = new PersonsDatabase("1 Adult","No Childs",1,0);
List<PersonsDatabase> personsList = PersonsDatabase.findWithQuery(PersonsDatabase.class,"Select adult_Text from PERSONS_DATABASE");
list = (ListView)findViewById(R.id.listView);
list.setAdapter(new ArrayAdapter<PersonsDatabase>(this, android.R.layout.simple_list_item_1, personsList));
}
}
I get something like: PACKAGENAME.PersonsDatabase#4264c038
But I want the values that I wrote in the constructor.
Thanks for help.
From the docs on ArrayAdapter:
However the TextView is referenced, it will be filled with the toString() of each object in the array. You can add lists or arrays of custom objects. Override the toString() method of your objects to determine what text will be displayed for the item in the list.
In short: just override the toString() method in your PersonsDatabase class to return the desired textual respresentation.
Alternatively:
To use something other than TextViews for the array display, for instance, ImageViews, or to have some of data besides toString() results fill the views, override getView(int, View, ViewGroup) to return the type of view you want.
(again from the docs). Plenty of examples out there on how to go about doing that.
Simply override the toString() method.
In that method, return whichever database value you want to retrieve.
In my case, I returned a variable name that I needed (i.e. message) :
#Override
public String toString() {
return message;
}
I am new to Android development and I am trying to create a ListFragment that can create a ListView from 3 ArrayList objects each containing 30 Strings. Each row would contain a string from each array.
In my reading, I have found that a ListView is essentially created from an ArrayAdapter. The only examples I've seen of this however only show 1 String[] array being used (http://goo.gl/Yrkn0k, http://goo.gl/hqkdl).
How can I pass the three arrays to ArrayAdapter to create this ListView?
ArrayAdapters can work on lists of any sort. If you need to have an ArrayAdapter operate on three separate lists at once, you will need to do two things:
Create a new object class that is the combination of the three lists, eg. an Item class that has three fields: Title, Description, Price. Once you have a suitable object, turn your three lists into a single list of your object.
Then you will need to create a custom adapter class that extends ArrayAdapter, overriding the getView method in order to properly display your items.
Edit
Example:
public class Item {
private String title, desc, price;
public Item(String title, String desc, String price) {
this.title = title;
...
}
*provide standard getters and setters*
}
...
ArrayList<Item> items = new ArrayList<Item>();
for(int i = 0; i < titles.length; i++) {
items.add(new Item(titles[i], descriptions[i], prices[i]);
}
Then new adapter should take the form of
private class CustomAdapter extends ArrayAdapter<Item> {
public CustomAdapter(ArrayList<Item> items) {
super(getActivity(), 0, items);
}
...
The ArrayAdapter<T> class is generic, so you can use it with java Collections. To do what you're trying to do, you could use an ArrayList<ArrayList<String>> or just build model objects that contain your 3 string fields and use ArrayList<YourModel>.
For Example:
public class MyAdapter extends ArrayAdapter<ArrayList<ArrayList<String>>>{
//Constructor
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ArrayList<String> current = getItem(position);
//Do Something
}
}