Android ListView Tutorial - FunDapter Class

Android ListView Tutorial When you want to display a list of products or some items in Android, you can use a  ListView . What you ha...

Android ListView Tutorial


When you want to display a list of products or some items in Android, you can use a ListView. What you have to do is to get a List or ArrayList of product names. It looks like this:
ArrayList<string> products = new ArrayList<string>();
products.add("Coke");
products.add("Pepsi");
products.add("Red Bull");
And then you can use an ArrayAdapter to adapt the data:
ArrayAdapter<string> adapter = new ArrayAdapter<string>(
this, android.R.layout.simple_list_item_1, products);
Assuming that you have created a ListView lvProduct in your layout, you can simply do like this:
ListView lvProduct;
lvProduct = (ListView) findViewById(R.id.lvProduct);
lvProduct.setAdapter(adapter);
Finally, you would see a simple list like this:
Image ListView by KosalGeek.com

Please take a closer look at ArrayAdapter class again!

You see, I used android.R.layout.simple_list_item_1 to display a list. In case you don't know, whenever you want to use a predefined layout or an image, you can always use it by starting with android. In this example, I used android.R.layout.simple_list_item_1. This simple layout can display only one text in a row. What if you want to display two texts in a row or to display a complex layout like the one you see on Facebook or Twitter that consists of an image, a description, a number of likes, comments, a share button etc? Yes you can do that by creating a custom adapter with a custom layout. Most people prefers BaseAdapter over ArrayAdapter because the BaseAdapter is better. Yes it is.

But here, I am not gonna spend my whole day talking about how to create a custom BaseAdapter again. You can find a huge amount of tutorials, blogs, and youtube videos about this. I doubt that you want to do it again. Maybe you come here to this blog for a better solution. OK, I want a generic class that can take a List/ArrayList of any model class and any custom layout, and finally it magically generates an adapter for a ListView for me.

It took me quite a while to find out a solution for that. First, I thought maybe I had to create a generic adapter myself. I spent some times with Java reflection but I got tired. I was like, how come no one never encountered that situation? I googled again and found many answers on StackOverflow, but not relevant at all. Many of them were just to some specific problems, not a general one. I kept looking at chosen answers, at other answers, at some down voted answers, at comments, actually everywhere. I finally found a tiny comment suggested a link to https://github.com/amigold/FunDapter. I quickly clicked it. Yes, finally someone had a gut to do it and he did it well.

His name is Ami Goldenberg. He posted a few repos including FunDapter. It is lovely. The code is elegant. Thanks to him, I don't have to write the class myself again. This post "Android ListView Tutorial" is dedicated to his work.

As you can see in his GitHub repo, he introduced a problem and a solution for that too. Since his code gave to MIT Open Source License, I believe I can use and publish his work. OK, here we go.

FUNDAPTER

I. How to Setup Fundapter

You need to add a line of code below to your dependencies of build.gradle (Module: app).
compile 'com.github.amigold.fundapter:library:1.0'

II. Before Fundapter Library

1. Create a Model Class

First, you need to create a model class just as usual. It is a class that maps to attributes of a database table. Say you have a table tbl_product with 4 attributes (id, name, qty, price). So will create a model class like this:
public class Product{
    public Integer id;
    public String name;
    public Integer qty;
    public Double price;
}
You are free to make a setter/getter for each attribute. But for now I don't care about this much. Even a library GSON from Google that is used to parse a JSON text, it also makes the attributes public and without using the setters/getters. Please leave a comment below if you have a better way and I will be happy to see it.

2. Create a Custom Layout

You need a custom layout for your item in a ListView. You go to File menu > New > XML > Layout XML File > Give the layout a name, e.g. layout_product.xml. Below is a sample layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Name"
        android:id="@+id/tvName_layout_product" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Qty"
        android:id="@+id/tvQty_layout_product"
        android:layout_below="@+id/tvName_layout_product"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Price"
        android:id="@+id/tvPrice_layout_product"
        android:paddingRight="10dp"
        android:layout_below="@+id/tvName_layout_product"
        android:layout_toRightOf="@+id/tvName_layout_product"
        android:layout_toEndOf="@+id/tvName_layout_product"
        android:layout_marginLeft="66dp"
        android:layout_marginStart="66dp" />

</RelativeLayout>
Image Custom Layout by KosalGeek.com

In the layout, I created 3 TextViews: tvName_layout_product, tvQty_layout_product, and tvPrice_layout_product. These names are important for the BindDictionary class to bind them correctly.

III. Use FunDapter Library

The Fundapter library has two main classes: one is BindDictionary and another is Fundapter.

1. Use BindDictionary To Bind an ArrayList to a Model Class

The BindDictionary class is used to bind data from a model class to a custom layout. You might wanna know why we need this? If you recall, when you create a custom BaseAdapter or ArrayAdapter, you need to override getView method, right? In the method, you assign each attribute of a model class to a correct widget, e.g. TextView or ImageView, in a custom layout. Now BindDictionary is the class for that. You no longer need to implement the getView method anymore.

I am going to implement the BindDictionary by using the sample code above. The model class is Product and the custom layout is layout_product.xml.

ArrayList of Product

But before that, let's add some data into an ArrayList products:
ArrayList products = new ArrayList();
Product p1 = new Product();
p1.id = 1;
p1.name = "Coke";
p1.qty = 20;
p1.price = 0.5;
products.add(p1);

Product p2 = new Product();
p2.id = 2;
p2.name = "Pepsi";
p2.qty = 15;
p2.price = 0.5;
products.add(p2);

BindDictionary

After you instantiate an object, e.g. dict, from BindDictionary, you can use it to bind each property, e.g. name to a correct widget, e.g. R.id.tvName_layout_product.  And here is the code of BindDictionary:
BindDictionary<Product> dict = new BindDictionary<Product>();
dict.addStringField(R.id.tvName_layout_product,
        new StringExtractor<Product>() {
            @Override
            public String getStringValue(Product product, int i) {
                return product.name;
            }
        }
);
dict.addStringField(R.id.tvQty_layout_product,
        new StringExtractor<Product>() {
            @Override
            public String getStringValue(Product product, int i) {
                return product.qty.toString();
            }
        }
);
dict.addStringField(R.id.tvPrice_layout_product,
        new StringExtractor<Product>() {
            @Override
            public String getStringValue(Product product, int i) {
                return product.price.toString();
            }
        }
);
The StringExtractor class is part of the library. And because it is a String, you need to convert the Integer or Double to String before you return, as in this example, return product.price.toString().

2. Use FunDapter to Create an Adapter for a ListView

Now the fun part is to use FunDapter. It is just as simple as this:
FunDapter adapter =new FunDapter(this, products, R.layout.layout_product, dict);

3. There Is A Bug - Important

Yes, you heard me right. Because in his project, he used a default icon ic_launcher, and if you also create a default blank activity which always uses the same ic_launcher icon, then you will have a manifest merge conflict. To solve this problem, there are three options, although the first one is not recommended:

1. Not Recommended. Remove android:icon="@mipmap/ic_launcher" from application tag in AndroidManifest.xml.

2. Add a new icon, say ic_mylogo. Then, your new code should be like this android:icon="@mipmap/ic_mylogo".

3. This option is recommended. Add xmlns:tools="http://schemas.android.com/tools" to your manifest tag, and add tools:replace="android:icon" to your application tag. See the screenshot below:
Image ic_launcher manifest merge conflict by KosalGeek.com

RESULT

After you follow all my steps and fix the bug, you should see your result like this:

Image Generic Adapter Custom ListView by kosalgeek.com

DOWNLOAD

You can download my complete source code on GitHub at https://github.com/kosalgeek/TestFundapter

Written by Oum SaokosalKosalGeek, Top12Review.

Disclaimer: 

Fundapter library is a work of Ami Goldenberg.

Photo Credit:

Samsung Galaxy S6 edge by Maurizio Pesce / CC BY

COMMENTS

Name

Android Java for Android
false
ltr
item
Android Programming Language Step by Step | KosalGeek: Android ListView Tutorial - FunDapter Class
Android ListView Tutorial - FunDapter Class
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqgXazw-euX6OgHdV2AN7XMHoIcFFpPONEvj3A5V_-hLNiC8fp1hcDGE8fjPYnqXNF25xI3F6_ySQmxjDh55Vc2bbCzgmAOvIcpLILuXGN-KE60vwDg0_KGHOrUVcy7-29KvgvD2_ncnE/s320/Android+ListView+Tutorial.jpg
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqgXazw-euX6OgHdV2AN7XMHoIcFFpPONEvj3A5V_-hLNiC8fp1hcDGE8fjPYnqXNF25xI3F6_ySQmxjDh55Vc2bbCzgmAOvIcpLILuXGN-KE60vwDg0_KGHOrUVcy7-29KvgvD2_ncnE/s72-c/Android+ListView+Tutorial.jpg
Android Programming Language Step by Step | KosalGeek
https://kosalgeek.blogspot.com/2015/09/android-listview-tutorial-fundapter.html
https://kosalgeek.blogspot.com/
http://kosalgeek.blogspot.com/
http://kosalgeek.blogspot.com/2015/09/android-listview-tutorial-fundapter.html
true
1541123312426289231
UTF-8
Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS CONTENT IS PREMIUM Please share to unlock Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy