How to Use an Arrayadapter in Android of Custom Objects

how to use an ArrayAdapter in android of custom objects

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.

Android custom ArrayAdapter with custom object

Here is working adapter code

public class RowAdapter extends ArrayAdapter<Row> {

private final Activity _context;
private final ArrayList<Row> rows;

public class ViewHolder
{
EditText RowNo;
EditText RowText;
}

public RowAdapter(Activity context, ArrayList<Row> rows)
{
super(context,R.layout.row_layout, R.id.row_id ,rows);
this._context = context;
this.rows = rows;
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;

if(convertView == null)
{
LayoutInflater inflater = _context.getLayoutInflater();
convertView = inflater.inflate(R.layout.row_layout,parent,false);

holder = new ViewHolder();
holder.RowNo = (EditText)convertView.findViewById(R.id.row_no);
holder.RowText = (EditText)convertView.findViewById(R.id.row_text);

convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}

holder.RowNo.setText(""+rows.get(position).RowNo);
holder.RowText.setText(rows.get(position).RowText);

return convertView;
}
}

Your getting exception at holder.RowNo.setText(rows.get(position).RowNo);

so replace it with

holder.RowNo.setText(""+rows.get(position).RowNo);

Android using custom object with ArrayAdapter, and communicating back views

In updateUIState(), you currently try to modify the EditTexts directly by calling setTheText(). Using the debugger I was able to see that this works to a certain extent - the EditText has the desired value at the end of setEditText(). But since the EditText is managed by an adapter, setting the text alone does not have the desired effect. If one calls e.invalidate() afterwards, the text is displayed correctly, if one also skips adapter.notifyDatasetChanged().

So it's basically possible to modify the Views. But it's a bad idea to do it that way.

Instead, you should change the data class. In your case, you need a way to set the desired text (String) for the EditText in TextInputLineBuilder. Then when getRowView() is called, this updated text should be used with EditText input.

Back to updateUIState(): it's correct to call notifyDatasetChanged() after modifying the data list, but you do not need to re-assign the adapter to the ListView.

How to use ArrayAdaptermyClass

Implement custom adapter for your class:

public class MyClassAdapter extends ArrayAdapter<MyClass> {

private static class ViewHolder {
private TextView itemView;
}

public MyClassAdapter(Context context, int textViewResourceId, ArrayList<MyClass> items) {
super(context, textViewResourceId, items);
}

public View getView(int position, View convertView, ViewGroup parent) {

if (convertView == null) {
convertView = LayoutInflater.from(this.getContext())
.inflate(R.layout.listview_association, parent, false);

viewHolder = new ViewHolder();
viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);

convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

MyClass item = getItem(position);
if (item!= null) {
// My layout has only one TextView
// do whatever you want with your string and long
viewHolder.itemView.setText(String.format("%s %d", item.reason, item.long_val));
}

return convertView;
}
}

For those not very familiar with the Android framework, this is explained in better detail here: https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView.

Adding a Custom Object to an ArrayAdapter. How to grab Data?

Your code will not work in its actual form. Do you really need lists of data in the ItemObject? My guess is no and you simply want a ItemObject that holds 3 Strings corresponding to the 3 views from your row layout. If this is the case:

class ItemObject {
String name;
String total;
String rating;// are you sure this isn't a float

public ItemObject(String total, String name, String rating) {
this.total = total;
this.name = name;
this.rating = rating;
}
}

Then your lists will be merged into a list of ItemObject:

List<String> names, ratings, totals;
ItemObject[] io= new ItemObject[3];
// use a for loop
io[0] = new ItemObject(totals.get(0), names.get(0), ratings(0));
io[1] = new ItemObject(totals.get(1), names.get(1), ratings(1));
io[2] = new ItemObject(totals.get(2), names.get(2), ratings(2));
adapter = new ItemAdapter(Items.this, io);
setListAdapter(adapter);

And the adapter class:

public class ItemAdapter extends ArrayAdapter<ItemObject> {

public ItemAdapter(Context context,
ItemObject[] objects) {
super(context, 0, objects);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// do the normal stuff
ItemObject obj = getItem(position);
// set the text obtained from obj
String name = obj.name; //etc
// ...

}

}

Android: Custom ArrayAdapter(s) for different custom objects

You can define your adapter like this:

 public class MyArrayAdapter<T> extends ArrayAdapter<T> 
{
HashMap<T, Integer> mIdMap = new HashMap<T, Integer>();

public MyArrayAdapter(Context context, int textViewResourceId, List<T> objects) {
super(context, textViewResourceId, objects);
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
}

How do I use an array of objects with the Android ArrayAdapter?

Using the ArrayAdapter is not enough, you will need to extend ArrayAdapter and create a custom adapter, so you can overwrite the rows creation to use your list layout. Please check this example:

public class CustomAdapter extends ArrayAdapter<Headers> {

Context context;
int layoutResourceId;
ArrayList<Headers> data = null;

public CustomAdapter(Context context, int resource, List<Headers> objects) {
super(context, resource, objects);
this.layoutResourceId = resource;
this.context = context;
this.data = (ArrayList) objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
HeaderHolder holder = null;

if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);

holder = new HeaderHolder();
holder.from = (TextView) row.findViewById(R.id.fromTextView);
holder.to = (TextView)row.findViewById(R.id.toTextView);
holder.subject = (TextView)row.findViewById(R.id.subjectTextView);

row.setTag(holder);
}
else
{
holder = (HeaderHolder) row.getTag();
}

Headers item = data.get(position);
holder.from.setText(item.getFrom());
holder.to.setText(item.getTo());
holder.subject.setText(item.getSubject());

return row;
}

private class HeaderHolder {
public TextView from;
public TextView to;
public TextView subject;

}
}

For the Activity, on the onCreate method:

ListView list = (ListView) findViewById(R.id.listView);
ArrayList<Headers> data = new ArrayList<Headers>();
data.add(new Headers("from", "to", "subject"));

ArrayAdapter adapter = new CustomAdapter(this, R.layout.list, data);
list.setAdapter(adapter);

You can see that the CustomAdapter is using HeaderHolder as part of the ViewHolder pattern so the list management is efficient.

ArrayList of custom class to ArrayAdapter for ListView

You can't use the ArrayAdapter in this way.

Since you are declaring ArrayAdapter<String> arrayAdapter you can't use a constructor with

ArrayAdapter(MainActivity,int,ArrayList<PipelineGridViewClass>)

It is the reason of your issue:

Error:(103, 53) error: no suitable constructor found for ArrayAdapter(MainActivity,int,ArrayList)
constructor ArrayAdapter.ArrayAdapter(Context,int,int,List) is not applicable

You can use somenthing like this:

 ArrayAdapter<PipelineGridViewClass> arrayAdapter = new ArrayAdapter<PipelineGridViewClass>(
MainActivity.this,
android.R.layout.simple_list_item_1,
pipelineview);

Pay attention to the doc:

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.

It means that you have to override the toString() of your PipelineGridViewClass class.



Related Topics



Leave a reply



Submit