how to use an ArrayAdapter in android of custom objects

How can I use the properties of a custom object in a Listview. If I implement an ArrayAdapter with a list of Strings it displays fine in Listview but when I use a list of custom objects, it just outputs the memory address.

The code I have up to now:

ArrayList<CustomObject> allObjects = new ArrayList<>();

allObjects.add("title", "http://url.com"));


  ArrayAdapter<NewsObject> adapter = new ArrayAdapter<NewsObject>(this,
                android.R.layout.simple_list_item_1, android.R.id.text1, allNews);


        // Assign adapter to ListView
        listView.setAdapter(adapter);


        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Uri uri = Uri.parse( "http://www.google.com" );
                startActivity(new Intent(Intent.ACTION_VIEW, uri));
            }
        });

There is a similar question here but that is not what I need since I just need to have the title show in list view and when they click extract the url.


An ArrayAdapter displays the value returned by the toString() method, so you will need to override this method in your custom Object class to return the desired String. You will also need to have at least a getter method for the URL, so you can retrieve that in the click event.

public class NewsObject {
    private String title;
    private String url;

    public NewsObject(String title, String url) {
        this.title = title;
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    @Override
    public String toString() {
        return title;
    }
    ...
}

In the onItemClick() method, position will be the index in the ArrayList of your custom Objects corresponding to the list item clicked. Retrieve the URL, parse it, and call startActivity().

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            NewsObject item = allNews.get(position);
            String url = item.getUrl();
            Uri uri = Uri.parse(url);
            startActivity(new Intent(Intent.ACTION_VIEW, uri));
        }
    });

Please note, I assumed your custom class is NewsObject, as that is what's used with your Adapter example.


If you want to use a methods of your custom class you need to implement a custor ArrayAdapter class... How to create this?

First step

Get your project and create a new class. Then extends class with ArrayAdapter<YourObject>{} and declare inside your atributes that you needs... My example:

public class Room_Adapter extends ArrayAdapter<Room_Object> {

//Declaration of Atributes
private ArrayList<Room_Object> Rooms_Array;
private final Activity context;
private final ListView lvBuinding;

Second

Declare a constructor for this class, always you need an Activity and ArrayList, put inside the others if you need... In my case I needs the listview... My example:

public Room_Adapter(Activity context, ArrayList<Room_Object> Rooms_Array,ListView lvBuinding) {
    super(context, R.layout.room_layout, Rooms_Array);

    this.context = context;
    this.Rooms_Array = Rooms_Array;
    this.lvBuinding = lvBuinding;
}

The super method nees your activity, custom layout (if you have it) and your array.

Third

Declare a static class or create a new one if you have a custom row layout. My example have a static class:

public static class Room_View{

    //Declaration of Atributes
    TextView RoomName;
    ImageView RoomState;
    TextView NoTroubles;

    Button btnRoomRow;

    ImageButton btnShowRoomTasks;
    ImageButton btnAddTasks;

    RelativeLayout RowLayout;
}

Fourth

Override method getView.

@Override
public View getView(int position, View ConvertView, ViewGroup parent) {

    //Declaration of Variables
    Room_View rowView; //Custom static class with controls
    LayoutInflater inflator = context.getLayoutInflater();

    if (ConvertView == null) {
        rowView = new Room_View();
        ConvertView = inflator.inflate(R.layout.room_layout,null,true); //Inflate your view with your custom view.


        rowView.RoomName = (TextView) ConvertView.findViewById(R.id.txtvRoom);
        rowView.RoomState = (ImageView) ConvertView.findViewById(R.id.ivRoomState);
        rowView.NoTroubles = (TextView) ConvertView.findViewById(R.id.txtvNoTroubles);

        rowView.btnRoomRow = (Button) ConvertView.findViewById(R.id.btnRoomRow);

        rowView.btnAddTasks = (ImageButton) ConvertView.findViewById(R.id.btnAddTask);
        rowView.btnShowRoomTasks = (ImageButton) ConvertView.findViewById(R.id.btnShowRoomTasks);

        rowView.RowLayout = (RelativeLayout) ConvertView.findViewById(R.id.rowLayout);


        ConvertView.setTag(rowView);
    }
    else
    {
        rowView = (Room_View) ConvertView.getTag();
    }

    //Here custom your control stats
    Room_Object Room = Rooms_Array.get(position);
    rowView.RoomName.setText(Room.getRoomName());

    rowView.NoTroubles.setVisibility(View.INVISIBLE);
    rowView.btnShowRoomTasks.setClickable(true);
    rowView.btnShowRoomTasks.setImageResource(R.drawable.list_3a4b66_50);
    rowView.btnShowRoomTasks.setOnClickListener(OnShowTasksClickListener);

    //This is for add ClickListiner in my buttons...
    rowView.btnAddTasks.setOnClickListener(OnAddTasksClickListener);
    rowView.btnRoomRow.setOnClickListener(OnAddTasksClickListener);

    if(Room.getStatus().equals("Checked")){
        rowView.RowLayout.setBackgroundColor(0xFFC7E6C7);
        rowView.btnShowRoomTasks.setClickable(false);
        rowView.btnShowRoomTasks.setImageResource(R.drawable.list_999999_50);
        rowView.RoomState.setImageResource(R.drawable.check_3ebf4b_50);
    }
    else if(Room.getStatus().equals("Blocked")){
        rowView.RowLayout.setBackgroundColor(0xFFDBC3E5);
        rowView.RoomState.setImageResource(R.drawable.key_9330e0_50);
    }
    else if(Room.getStatus().equals("Dirty")){
        rowView.RowLayout.setBackgroundColor(0xfffceedb);
        rowView.RoomState.setImageResource(R.drawable.icon_housekeeping_3_yellow);
    }
    else if(Room.getStatus().equals("Troubled")){
        rowView.RowLayout.setBackgroundColor(0xFFF4CECD);
        rowView.RoomState.setImageResource(R.drawable.wrench_eb3232_50);

        rowView.NoTroubles.setVisibility(View.VISIBLE);
        try {
            rowView.NoTroubles.setText(Integer.toString(Room.getNoTasks()));
        }
        catch (Exception ex){
            Log.e("-- Error --",ex.getMessage());
        }
    }

    //
    //Pay attention *************************************************
    //

    //Now if you needs to use your custom external class this is the site, now imagine that you need gets string from your custom class in the text view, then:

    //Declare class
    CustomClass object = new CustomClass();

    rowView.(CUSTOM CONTROL FROM YOUR STATIC CLASS).(METHOD OF CONTROL)(object.(CUSTOM METHOD OF YOUR OBJECT));

    //For example If you follows my sample then:
    rowView.NoTroubles.setText(object.getNumberOfTroubles().toString);


    return ConvertView;
}

//Listener Methods for my button controls
private View.OnClickListener OnShowTasksClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int positionSelected = lvBuinding.getPositionForView((View) v.getParent());
        int totalRooms = lvBuinding.getCount() - 1;
        int actualRoom = totalRooms - positionSelected;

        try{
            //Your code;
        }
        catch (Exception ex){
            Log.e("-- CustomError --", ex.getMessage());
        }
    }
};

private View.OnClickListener OnAddTasksClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int positionSelected = lvBuinding.getPositionForView((View) v.getParent());
        int totalRooms = lvBuinding.getCount() - 1;
        int actualRoom = totalRooms - positionSelected;

        try{
            //Your code;
        }
        catch (Exception ex){
            Log.e("-- CustomError --", ex.getMessage());
        }
    }
};
}

I think this is that you needs, if you need more info or same advice me and I try to helps you... Good luck, Eduardo!