How to use ArrayAdapter myClass
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.
ArrayAdapter MyClass attaching to a View
In your case best to use SimpleAdapter
You define an XML file which represents your list item. This XML file will contain TextViews
in which you will display your data from your MyInfoClass
. Say it's my_list_item.xml
<LinearLayout...>
<TextView android:id=name.../>
<TextView android:id=gender.../>
<TextView android:id=occupation.../>
</LinearLayout>
Suppose you have the data for them as MyInfoClass.getName(), .getGender(), .getOccupation()
You create a List of Maps each Map represents the data for one list item:
List<HashMap<String, String>> maps = new ArrayList<HashMap<String, String>>();
You fill this list with your information:
for(int i=0; i<myArray.size(); ++i) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", myArray.get(i).getName());
map.put("gender", myArray.get(i).getGender());
map.put("occupation", myArray.get(i).getOcupation());
maps.add(map); // add this entry to the list
);
You also create 2 arrays : one with the names of the keys( "name", "occupation", "gender") another one with the ids of corresponding resources. They are String[] from, int[] to
, so the data in the map with a key from[n]
gets displayed in a view with id to[n]
String[] from = new String[] {"name", "gender", "occupation" };
int[] to = {R.id.name, R.id.gender, R.id.occupation }
Then you create a SimpleAdapter
using that list and you XML file:
SimpleAdapter mAdapter = new SimpleAdapter(YourActivity.this, maps, R.layout.my_list_item, from, to);
then you set this adapter in your ListActivity
and the list will be displayed:
setListAdapter(mAdapter);
If you want to display something other than Strings you will need to subclass SimpleAdapter and redefine some functions like setViewText
, setViewImage
but I don't know much about that
ArrayAdapter with class
So i managed to solve my own problem. My issue was that i couldn't change "ArrayList" to "ArrayList", horario being my class i wanted but that's because "horario" was declared in a bigger class. So i just had to change to "ArrayList", "mostraHorario" being the bigger class.
How to use more than one textview within an ArrayAdapter for a listview?
Usually I'm extending ArrayAdapter
in such cases. Generally You need to override only two functions in the adapter - getView() and one of constructors.
The code of the adapter is following:
/** class to act as list adapter for rows List */
private static class FourTextListAdapter extends ArrayAdapter<MyDataClass> {
/** To cache views of item */
private static class ViewHolder {
private TextView text1;
private TextView text2;
private TextView text3;
private TextView text4;
/**
* General constructor
*/
ViewHolder() {
// nothing to do here
}
}
/** Inflater for list items */
private final LayoutInflater inflater;
/**
* General constructor
*
* @param context
* @param resource
* @param textViewResourceId
* @param objects
*/
public FourTextListAdapter(final Context context,
final int resource,
final int textViewResourceId,
final List<User> objects) {
super(context, resource, textViewResourceId, objects);
this.inflater = LayoutInflater.from(context);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
View itemView = convertView;
ViewHolder holder = null;
final MyDataClass item = getItem(position);
if(null == itemView) {
itemView = this.inflater.inflate(R.layout.four_texts_item, parent, false);
holder = new ViewHolder();
holder.text1 = (TextView)itemView.findViewById(R.id.text1);
holder.text2 = (TextView)itemView.findViewById(R.id.text2);
holder.text3 = (TextView)itemView.findViewById(R.id.text3);
holder.text4 = (TextView)itemView.findViewById(R.id.text4);
itemView.setTag(holder);
} else {
holder = (ViewHolder)itemView.getTag();
}
holder.text1.setText(item.getText1());
holder.text2.setText(item.getText2());
holder.text3.setText(item.getText3());
holder.text4.setText(item.getText4());
return itemView;
}
}
ArrayAdapter onResume() confusion
I think you should store your Adapter
in Activity
, populate it only once at start and become independent of Fragment's
lifecycle. Make a getter for it and access it from Fragment
via (MyActivity) getActivity().getMyAdapter()
.
About your second question: if user switches to another app, there are 3 possible scenarios:
- User comes back quickly, nothing is changed.
- User comes back after a while, your app was cached and restored -
still you'll get the same state of objects. - User leaves your app for a long time, it's killed. App'll have to
restart from scratch.
In all cases, you're safe.
constructor of class ArrayAdapter
Every extending class must have minimum one constructor matching parent class. So Your class must have constructor with one line and calling super on it, no own code is required.
public MyListAdapter(Context context, int resource ) {
super(context, resource);
//your code
}
But when You create your Adapter you are using constructor so You can create any constructor, important is to use super in it.
In constructor You can for example implement code to set data to list from database.
You can for example create constructor like that:
public MyListAdapter(Context context) {
super(context, R.layout.row_view);
//your code
}
and
ListView listView = (ListView) rootView.findViewById(R.id.listview);
ListAdapter listAdapter = new MyListAdapter(getContext());
listView.setAdapter(listAdapter);
Customed ArrayAdapter
By default, ArrayAdapter will display the text returned by the toString
method of your objects. In this simple case, you can simply override the toString
method for Categoria
and return the nombre
field:
public class Categoria {
...
@Override
public String toString() {
return this.nombre;
}
}
If your application needs ever change and you require a more complicated layout, you can override the getView
method of ArrayAdapter
to bind data from Categoria
to a more complicated view.
Related Topics
How to Add a Button Dynamically in Android
Recyclerview and Handling Different Type of Row Inflation
How to Change Position of Toast in Android
How to Prevent Screen Capture in Android
Android Get Real Path by Uri.Getpath()
How to Inflate One View with a Layout
Android - Package Name Convention
Changing the Background Drawable of the Searchview Widget
Animate Change of View Background Color on Android
Java.Lang.Runtimeexception: Unable to Instantiate Activity Componentinfo
Android Studio Add External Project to Build.Gradle
Where Is Debug.Keystore in Android Studio
Android- Error:Execution Failed for Task ':App:Transformclasseswithdexforrelease'