Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
fabh
946 PointsCustom listview course?
Would it be possible if someone could do a deep dive on Custom Listviews for Android?
I searched on the internet and did not find anything good..
I'm reaally confused with custom Listviews and Custom Adapters etc..
That reaally would be great ! :)
20 Answers
Ben Jakuben
Treehouse TeacherIt's unfortunately a lot of code, but the basic idea is:
- Design your layout
- Create an adapter that adapts your data for the layout. The adapting happens in the
getView()method, which gets called to set up each row in your list. - Use your adapter in your activity
The following is untested code, but hopefully it's good enough to get you started. Feel free to post follow ups, though my availability in the forum is more limited on the weekends. :)
First you'll need a layout like this, named something like custom_row_layout.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="15dp"
android:scaleType="fitCenter"
android:background="@drawable/test_image" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/imageView1"
android:layout_alignParentTop="true"
android:text="test1" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/imageView1"
android:layout_below="@id/textView1"
android:text="test2" />
</RelativeLayout>
Then you'll need a custom adapter class, like this. Notice that custom_row_layout is used twice. This is based on having a CustomObject class that holds your text data for each item (and possibly the image filename):
public class CustomAdapter extends ArrayAdapter<CustomObject> {
public static final String TAG = CustomAdapter.class.getSimpleName();
protected Context mContext;
protected LayoutInflater mInflater;
protected ArrayList<CustomObject> mItems;
public CustomAdapter(Context context, ArrayList<CustomObject> items) {
super(context, R.layout.custom_row_layout, items);
mContext = context;
mItems = items;
mInflater = LayoutInflater.from(mContext);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_layout, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.imageView1);
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.textView2 = (TextView) convertView.findViewById(R.id.textView2);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
final CustomObject item = mUsers[position];
holder.imageView1.seBackgroundImage(mContext.getDrawable(R.drawable.image_name);
holder.textView1.setText(item.getText1());
holder.textView2.setText(item.getText2());
return convertView;
}
private static class ViewHolder {
ImageView imageView;
TextView textView1;
TextView textView2;
}
}
Then you use the adapter in an Activity, like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_users);
// mItems will be an ArrayList<CustomObject>
CustomAdapter adapter = new AdapterAdapter(MainActivity.this, mItems);
setListAdapter(adapter);
}
There's a lot I'm glossing over for time's sake, but I will definitely cover this in video down the road!
Ben Jakuben
Treehouse TeacherDefinitely on the list of topics to be covered! In the mean time, check out this tutorial from vogella.com: http://www.vogella.com/articles/AndroidListView/article.html
Specifically, follow the section called "Developing a custom adapter."
fabh
946 PointsThank you for this link!
I already knew that tutorial, but what gets me confused is the difference between a custom adapter and the listayout..
And the vogella tutorial is confusing for me because there are so many different things :/
But I'll try searching for tutorials :)
Ben Jakuben
Treehouse TeacherSure - I think it takes writing a few custom adapters to put all the pieces together. For me it definitely helps to isolate the layout and the adapter. I design the layout how I want it and then work on the adapter to make sure I'm getting the right data elements in the right spots in the layout.
I don't have a lot of publicly-available code to share, but if an example would help, check out the UsersAdapter of this ReadMe app I wrote for a Treehouse presentation. The adapter is used in the SelectUsersActivity, but perhaps it will show you how I tie the custom layout to the custom UsersAdapter.
Feel free to drop questions in here and I'll try to answer in case it will help anyone else!
fabh
946 PointsThe app is awesome! When I know android programming a bit better, I want to do a similar app for my website with the same plugins and login :)
So your app helps me to learn a lot! Thank you !
Ben Jakuben
Treehouse TeacherCool - very glad to hear it! I know I like to learn by example when I can. Also, I recorded a workshop for Treehouse on the Parse.com integration, and that should be available before too long.
fabh
946 PointsI found a very good eboook for listviews and other elements of android developing :)
http://www.amazon.de/Android-Application-Development-Cookbook-Building/dp/1118177673
The book explains customadapters and so on very simple and easy to understand :)
Ben Jakuben
Treehouse TeacherI have this Android Recipes book from Apress. I haven't read much of it yet, but it looks good, and I like the author (from Twitter). I got the ebook for half off--they run promos like that now and then.
fabh
946 PointsJust in case someone reads this
http://tekeye.biz/2012/two-line-lists-in-android
this is a very good tutorial explaining the listview and the hashmap
Ben Jakuben
Treehouse TeacherThanks @Fabian! I'm going to add that post to the video notes. I wish two line lists were simpler in Android! Sometimes iOS has all the fun...
fabh
946 Points@Ben Sooorry if the notifications you get may annoy you :P
I'm now trying to write my first "useful" app..
It's reall simple at first a Array with strings gets initialized
private String[][] picturelist= {{ "example", "example" }, };
then I push this into a list with this
HashMap<String, String> item; for (int i = 0; i < bilderliste.length; i++) { item = new HashMap<String, String>(); item.put("category", bilderliste[i][0]); item.put("description", bilderliste[i][1]);
list.add(item);
}
sa = new SimpleAdapter(this, list, R.layout.bilderliste, new String[] {
"category", "description" }, new int[] { R.id.category,
R.id.description });
that works out pretty good, but now I want to add a picture to the array.. and don't really know how to do that.. I searched a lot of tutorials, but they were not what I needed..
Maybe someone could help me a bit, I'm really stuck..
Ben Jakuben
Treehouse Teacher@Fabian, helping you and the other members is why I love my job!
Quick question: Where do you plan on getting the images from? Will they be in your res directory, or will you download them from the web? Downloading from the web is harder, but there's an open source library you can use from GitHub that makes it super easy. Let me know which you're after and I can walk you through it. But basically you need to create a custom layout file for each row that has an ImageView and two TextViews. Then you need to map everything manually like my UsersAdapter example from above.
fabh
946 Points@Ben And that's why we (I) love you ! :D
I'm planning to get them from my res folder, I already did a xml file with two lines and one image, I already tried some things from tutorials.
But I'm really confused now.. :/
fabh
946 PointsThank you a lot! :)
That really helps
But what is the "CustomObject"?
Maybe It's obvious and I'm just to confused right now :P
And a main question for me is: When to use which ArrayLists and when to use what kind of adapters.. ArrayLists are confusing for me, because we already have a Array, why should we something like a ArrayList?
Ben Jakuben
Treehouse TeacherSorry, I shouldn't have assumed anything! CustomObject is meant to be a file named CustomObject.java that you make like this:
public class CustomObject {
protected String mText1;
protected String mText2;
protected String mImageFilename;
public CustomObject(String s1, String s2, String imageFilename) {
mText1 = s1;
mText2 = s2;
mImageFilename = imageFilename;
}
public String getText1() {
return mText1;
}
public void setText1(String text) {
mText1 = text;
}
// ... other getters and setters omitted ...
}
You would create an ArrayList of these based on your data rather than using an array of Strings (or a two-dimensional array of Strings like your `picturelist`).
Oftentimes you can choose a regular array or ArrayList. I think my example would work with a regular array of CustomObjects... ArrayList gives you a little more functionality than a regular array, and some adapters require an ArrayList instead. Let me know if changing to a regular array works!
fabh
946 PointsI now found a (kind of) library for doing lists really easy
https://github.com/thest1/LazyList
and
https://github.com/nostra13/Android-Universal-Image-Loader
which is based on the above, but further maintained :)
I think i'll use this, because i don't like to reeinvent the wheel :D
I probably can't answer, because after i bought my SGS4, I'm to poor for treehouse ^^
Ben Jakuben
Treehouse TeacherAwesome - good finds! :) Thanks for sharing the links, too! Here's a good site for discovering new libraries: Android Views
fabh
946 PointsFound another nice tutorial:
fabh
946 PointsI have a major problem with my listview..
I managed to do a customadapter using LazyAdapter and a class for my object..
the listview shows up only when I install the app on my device, after that the listview gets blank..
Ben Jakuben
Treehouse TeacherWe don't officially support custom projects from members, but if you want to zip up your project and email it to help@teamtreehouse.com then I can take a look and see if anything jumps out. Make sure you indicate that it's Android and for me in your subject (like "Android project files for Ben").