0

I already asked a similar question here and one user suggested to subclass ArrayAdapter, but I have issues with that. Here is my problem:

I use a HashMap<String, String> and a SimpleAdapter object to display user data in my ListView, but now I want to replace the HashMap<String, String> with an ArrayList<User>(); containing real user objects.

Here is the old code:

HashMap<String, String> map = new HashMap<String, String>();

                map.put(TAG_USERNAME, c.getString(TAG_USERNAME));
                map.put(TAG_FIRSTNAME, c.getString(TAG_FIRSTNAME));
                map.put(TAG_LASTNAME, c.getString(TAG_LASTNAME));
                map.put(TAG_ADDRESS, c.getString(TAG_ADDRESS));
                usersList.add(map);

[...]

ListAdapter adapter = new SimpleAdapter(this, usersList,
                    R.layout.single_user, new String[] { TAG_USERNAME,
                            TAG_FIRSTNAME, TAG_LASTNAME, TAG_ADDRESS },
                    new int[] { R.id.textViewUsername, R.id.textViewFirstName,
                            R.id.textViewLastName, R.id.textViewAddress });

Now, as suggested, I tried to subclass ArrayAdapter, but I have no plan how the getView(int, View, ViewGroup) should look like, to achieve my objective.

Here is my current code:

public class UserArrayAdapter extends ArrayAdapter<User> {

    private Context mcon;
    private List<User> userList;

    public UserArrayAdapter(Context context, int resource,
            List<User> userList) {
        super(context, resource);
        mcon = context;
        this.userList = userList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        for (User usr : userList) {
            findViewById(R.id.textViewUsername).setText(usr.getFirstName());
        }
        return super.getView(position, convertView, parent);
    }

}

Here is the User class:

public class User {

    private String username, firstName, lastName, address;

    public User(String username, String firstName, String lastName,
            String address) {
        setUsername(username);
        setFirstName(firstName);
        setLastName(lastName);
        setAddress(address);
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        if (username == null) {
            throw new IllegalArgumentException("username is null.");
        }
        this.username = username;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        if (firstName == null) {
            throw new IllegalArgumentException("firstName is null.");
        }
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        if (lastName == null) {
            throw new IllegalArgumentException("lastName is null.");
        }
        this.lastName = lastName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        if (address == null) {
            throw new IllegalArgumentException("address is null.");
        }
        this.address = address;
    }
}

And I thought I would call it like this:

    ListAdapter ad = new UserArrayAdapter(this, R.layout.single_user, usersArrList);

Any help would be greatly appreciated.

1
  • Show us your User class Commented Oct 10, 2014 at 16:04

2 Answers 2

2

I'd suggest bypassing ArrayAdapter altogether as, since you're going to be doing custom work, you're going to be duplicating effort done by the adapter internally. Implementation is trivial anyway. Just subclass BaseAdapter:

public class UserAdapter extends BaseAdapter {
    private final List<User> mUsers;
    private final LayoutInflater mInflater;

    public UserAdapter(Context ctx, Collection<User> users) {
        mUsers = new ArrayList<User>();
        mInflater = LayoutInflater.from(ctx);
        if (users != null) {
            mUsers.addAll(users);
        }
    }

    @Override
    public int getCount() {
        // Just return the number of users in your data set
        return mUsers.size();
    }

    @Override
    public long getItemId(int pos) {
        // Mostly irrelevant if you're not using Cursors
        return pos;
    }

    @Override
    public User getItem(int pos) {
        // Just return the item at the specified position
        return mUsers.get(pos);
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {
        UserViewHolder uvh;

        if (convertView == null) {
            // Only inflate the layout if there's not already a recycled view
            convertView = mInflater.inflate(R.layout.single_user, parent, false);

            // Tag the view with a class holding the views found with 
            // findViewById() to prevent lookups later
            uvh = new UserViewHolder(convertView);
            convertView.setTag(uvh);
        } else {
            // If the view is non-null, then you will have already
            // created the view holder and set it as a tag
            uvh = (UserViewHolder) convertView.getTag();
        }

        // Now just get the user at the specified position and
        // set up the view as necessary
        User user = getItem(pos);
        uvh.usernameTxt.setText(user.getUsername());

        return convertView;
    }

    public static class UserViewHolder {
        public final TextView usernameTxt;

        public UserViewHolder(View v) {
            usernameTxt = (TextView) v.findViewById(R.id.textViewUsername);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Do like this :

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    // Getting the view to use (letting ArrayAdapter do this job)
    View v = super.getView(position, convertView, parent);

    // Getting the current user
    User usr = userList.get(position);

    // Filling the firstname in the textview
    ((TextView) v.findViewById(R.id.textViewUsername)).setText(usr.getFirstName());

    return v;
}

Then, set your adapter in the listView

ListAdapter ad = new UserArrayAdapter(this, R.layout.single_user, usersArrList);
listView.setAdapter(ad);

3 Comments

Thank you for your help. I did exactly as suggested and there is no error in my LogCat, but I can't see any users in the app. Any ideas how to debug this?
Could you edit your first post with the activity code, the one concerning the listView / adapter
Thank you for your help, but I solved it with the solution from kcoppock.

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.