1

enter image description here

I am trying to make a custom listview. The list is declared as below

List<DocRow> doctors = new ArrayList<>();

This list is then being populated.

My custom array adapter is in a separate class with its constructor declared as below.

public class DocAdapter extends ArrayAdapter<DocRow>{
    Context context;
    int resource;
    ArrayList<DocRow> doctors;
    private LayoutInflater inflater;

    public DocAdapter(@NonNull Context context, @LayoutRes int resource, ArrayList<DocRow> doctors) {
        super(context, resource, doctors);
        this.context = context;
        this.resource = resource;
        this.doctors = doctors;
        inflater = LayoutInflater.from(context);
    }

Now in my main activity, I am trying to create a new custom array adapter by passing off my list (which is a valid parameter), it isn't accepted. The code for creation and setting of adapter for linking the listview with the list is below.

DocAdapter adapter = new DocAdapter(getApplicationContext(), R.layout.doc_row, doctors);
docList.setAdapter(adapter);

Can anyone explain what is the issue? The link for error screenshot is above. I tried searching for this specific issue, but haven't been able to find a solution that works.

4
  • have you tired with passing this or classname.this as context Commented Nov 14, 2017 at 11:33
  • 2
    Can you post your code for 'doctors' ArrayList<DocRow> from activity? Commented Nov 14, 2017 at 11:35
  • @ShylendraMadda yes, didn't work. Commented Nov 14, 2017 at 11:46
  • @Reena nevermind, got resolved by the answer below. Commented Nov 14, 2017 at 11:46

2 Answers 2

2

Change your constructor argument to List instead of ArrayList as you are passing list in it.

 List<DocRow> doctors;

 public DocAdapter(@NonNull Context context, @LayoutRes int resource, List<DocRow> doctors) {
        super(context, resource, doctors);
        this.context = context;
        this.resource = resource;
        this.doctors = doctors;
        inflater = LayoutInflater.from(context);
    }

As pointed by @Tim, here is a little detail about why this is needed.

When an instance is initialized, it may be initialized with one of its child classes but the object remains an instance of Super class only(Due to runtime polymorphism) and therefore the methods that consume this instance either expect super class or the instance should be casted to superclass before passing it on.

The easiest way to identify is to always look at the type on the left-hand side instead.

List a=new ArrayList();

In above example, the instance is actually an arraylist but it is of Type List.

Sign up to request clarification or add additional context in comments.

4 Comments

you should explain why you think this is necessary
where are you quoting from?
Thanks, this works. I realized that I declared my list as List and not ArrayList and hence, it was not taking. Now, I have made everything List and it works.
Origin link is not required all the time, putting them will be a trivial addition and will make it only verbose, thanks for review however.
0

A parent class's reference can store subclass's object, but the reverse is not true.

Here, in the constructor of your adapter, you have ArrayList<DocRow> as your parameter type, but your doctors list is of type List<DocRow>. You, you're passing a List<> object to an ArrayList<> reference.

To solve it, either change your doctors variable type to ArrayList<>, or your constructor parameter type to List<>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.