Monday, July 13, 2015

ListView with Custom Adapter

We just created a simple listview using simple ArrayAdapter in the last tutorial which displayed the list of Strings in the vertical list. In this tutorial we will create a listView with a more complex data.



 Our objective for this session is to create a ListView displaying Name of Android Versions along with their versions. Let's begin by planning what our list item will be like.

Above picture shows how each of our ListView item will look like. So let's start by creating a new project with blank Activity.

Then, add the ListView in the layout of Main Activity.


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">  
   
   <ListView  
     android:id="@+id/listView"  
     android:layout_width="match_parent"  
     android:layout_height="match_parent"/>  
   
 </RelativeLayout>  
   


Let's define our Model for the list item, Let's create a Java class named AndroidVersion.

 package com.technoguff.listviewexample;  
   

 public class AndroidVersion {  
     
   private String codeName;  
   private String version;  
   private int icon;  
   
   
   public String getCodeName() {  
     return codeName;  
   }  
   
   public void setCodeName(String codeName) {  
     this.codeName = codeName;  
   }  
   
   public String getVersion() {  
     return version;  
   }  
   
   public void setVersion(String version) {  
     this.version = version;  
   }  
   
   public int getIcon() {  
     return icon;  
   }  
   
   public void setIcon(int icon) {  
     this.icon = icon;  
   }  
 }  
   


Then , create a layout for the item view. Create new layout file named layout_item.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:orientation="vertical" android:layout_width="match_parent"  
   android:layout_height="match_parent">  
   <ImageView  
     android:id="@+id/ivIcon"  
     android:layout_width="64dp"  
     android:layout_height="64dp"   
     android:layout_margin="5dp"/>  
   
   <TextView  
     android:id="@+id/codeName"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_toRightOf="@+id/ivIcon"  
     android:textStyle="bold"  
     android:textSize="20sp"  
     />  
   
   <TextView  
     android:id="@+id/version"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_toRightOf="@id/ivIcon"  
     android:layout_below="@+id/codeName"  
     />  
   
 </RelativeLayout>  


Now, Create some sample data for our listview by creating an ArrayList of AndroidVersions in MainActivity and create drawable-mdpi folder in res folder of our project. And then place the icons for different versions. GET THE ICONS HERE.


 public class MainActivity extends AppCompatActivity {  
   
   
   
   private ArrayList<AndroidVersion> mVersionList;  
   private ListView mListView;  
   
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
   
     //Sample Data :: For this tutorial, let's just create sample data in the main activity. In real projects  
     // we will either get the data for our list item from webservices or local storage.  
   
     mVersionList = new ArrayList<AndroidVersion>();  
     AndroidVersion version = new AndroidVersion();  
     version = new AndroidVersion();  
     version.setCodeName("Cupcake");  
     version.setVersion("Android 1.5");  
     version.setIcon(R.drawable.cupcake);  
     mVersionList.add(version);  
   
     version = new AndroidVersion();  
     version.setCodeName("Donut");  
     version.setVersion("Android 1.6");  
     version.setIcon(R.drawable.donut);  
     mVersionList.add(version);  
   
     version = new AndroidVersion();  
     version.setCodeName("Eclair");  
     version.setVersion("Android 2.0");  
     version.setIcon(R.drawable.eclair);  
     mVersionList.add(version);  
   
     version = new AndroidVersion(); 
     version.setCodeName("Froyo");  
     version.setVersion("Android 2.2");  
     version.setIcon(R.drawable.froyo);  
     mVersionList.add(version);  
   
     version = new AndroidVersion();  
     version.setCodeName("Gingerbread");  
     version.setVersion("Android 2.3");  
     version.setIcon(R.drawable.gingerbread);  
     mVersionList.add(version);  
   
 ......  
   
 ......  
   
   


Now, we have the sample data for the list items, we will create our custom adapter class by extending ArrayAdapter and add a constructor..

 package com.technoguff.customadapterexample;  
   
 import android.content.Context;  
 import android.widget.ArrayAdapter;  
   
 import java.util.List;  
   
 /**  
  * Created by darshanz on 7/13/15.  
  */  
 public class CustomAdapter extends ArrayAdapter<AndroidVersion> {  
     
   public CustomAdapter(Context context, int resource, List<AndroidVersion> objects) {  
     super(context, resource, objects);  
   }  
     
 }  


This adapter class will act as a bridge between our data and the list item. Adapter class will do following functions.
1. will use the layout for list item
2.  add data to different views in the item layout.


Before moving forward we need to know that listview will recycle the item layouts when they go out of the screen while scrolling and same layout will be used for other data items.   Since it is expensive to call findViewById() each time the item is displayed in the screen we will use ViewHolder for holding the views in our item layout and reuse them to avoid the overload of find the views from layout.

So the next step is to create a simple ViewHolder class in our Adapter.

 class ViewHolder{  
     ImageView ivIcon;  
     TextView tvCodeName;  
     TextView tvVersion;  
   }  
   


Now let's add a member variable for the List if items that we get from MainActivity, and since we will need to inflate the layout using the getLayoutInflater method form activity let's change our constructor a little so that it has Activity as a parameter.


  private ArrayList<AndroidVersion> mVersionList;  
   private LayoutInflater inflater;  
     
   public CustomAdapter(Activity activity, int resource, ArrayList<AndroidVersion> objects) {  
     super(activity, resource, objects);  
   
     mVersionList = objects;  
     inflater = activity.getLayoutInflater();  
   }  

Now, in order to inflate our layout and set data let's override the getView() method of the LisView and add following code.


 @Override  
   public View getView(int position, View convertView, ViewGroup parent) {  
   
     ViewHolder holder;  
   
   
     if(convertView == null){  
       convertView = inflater.inflate(R.layout.layout_item, null);  
       holder = new ViewHolder();  
       holder.tvCodeName = (TextView)convertView.findViewById(R.id.codeName);  
       holder.tvVersion = (TextView)convertView.findViewById(R.id.version);  
       holder.ivIcon = (ImageView)convertView.findViewById(R.id.ivIcon);  
   
       convertView.setTag(holder);  
   
     }else{  
   
       holder = (ViewHolder)convertView.getTag();  
     }  
   
   
     AndroidVersion version = mVersionList.get(position);  
   
     holder.tvCodeName.setText(version.getCodeName());  
     holder.tvVersion.setText(version.getVersion());  
     holder.ivIcon.setImageResource(version.getIcon());  
   
   
   
     return convertView;  
   }  



Now after writing getView method our Adapter should look like this.


 package com.technoguff.customadapterexample;  
   
 import android.app.Activity;  
 import android.content.Context;  
 import android.view.LayoutInflater;  
 import android.view.View;  
 import android.view.ViewGroup;  
 import android.widget.ArrayAdapter;  
 import android.widget.ImageView;  
 import android.widget.TextView;  
   
 import java.util.ArrayList;  
 import java.util.List;  
   
 /**  
  * Created by darshanz on 7/13/15.  
  */  
 public class CustomAdapter extends ArrayAdapter<AndroidVersion> {  
   
   
   private ArrayList<AndroidVersion> mVersionList;  
   private LayoutInflater inflater;  
   
   public CustomAdapter(Activity activity, int resource, ArrayList<AndroidVersion> objects) {  
     super(activity, resource, objects);  
   
     mVersionList = objects;  
     inflater = activity.getLayoutInflater();  
   }  
   
   
   @Override  
   public View getView(int position, View convertView, ViewGroup parent) {  
   
     ViewHolder holder;  
   
   
     if(convertView == null){  
       convertView = inflater.inflate(R.layout.layout_item, null);  
       holder = new ViewHolder();  
       holder.tvCodeName = (TextView)convertView.findViewById(R.id.codeName);  
       holder.tvVersion = (TextView)convertView.findViewById(R.id.version);  
       holder.ivIcon = (ImageView)convertView.findViewById(R.id.ivIcon);  
   
       convertView.setTag(holder);  
   
     }else{  
   
       holder = (ViewHolder)convertView.getTag();  
     }  
   
   
     AndroidVersion version = mVersionList.get(position);  
   
     holder.tvCodeName.setText(version.getCodeName());  
     holder.tvVersion.setText(version.getVersion());  
     holder.ivIcon.setImageResource(version.getIcon());  
   
   
   
     return convertView;  
   }  
   
   class ViewHolder{  
     ImageView ivIcon;  
     TextView tvCodeName;  
     TextView tvVersion;  
   }  
   
 }  
   



Finally set this adapter to the listview. In onCreate method of MainActivity, initialize the mListview and set the adapter.

   
     mListView = (ListView)findViewById(R.id.listView);  
     mListView.setAdapter(new CustomAdapter(this, R.layout.layout_item, mVersionList));  
   


Then run the project.





We can see the list items now have images code names and versions.







Introduction to ListView


 In our previous tutorial, we saw how we can arrange different views in the screen using various Layouts. Now, we will see how we can arrange the views in a vertically scrollable List. 





Let’s begin with creating an Android Application with a blank Activity. (If you are new to Android development please follow this tutorial to see how to create an android project)


Now in the layout file (activity_main.xml), add a ListView. With mandatory attributes, layout_width and layout_height, let’s also add id attribute so that we can access this ListView from Java code.


1:  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
2:    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
3:    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"  
4:    android:paddingRight="@dimen/activity_horizontal_margin"  
5:    android:paddingTop="@dimen/activity_vertical_margin"  
6:    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">  
7:    
8:    <ListView  
9:      android:id="@+id/listView"  
10:      android:layout_width="match_parent"  
11:      android:layout_height="match_parent"/>  
12:    
13:  </RelativeLayout>  
14:    


Now lets access this ListView from MainActivity.java and add some data to it. For this we define a ListView and an array of item to display in the listView.



 public class MainActivity extends AppCompatActivity {  
   
   private ListView mListView;  
   
       private  String[] items = {"Cupcake", "Donut", "Froyo", "GingerBread", 
            "Honeyomb", "IceCream Sandwich", "Jelly Bean", "Kitkat", "Lollipop", 
            "Android M", "Android N", "Android O", "Android P", "Android Q", "Anroid R", 
            "Android S", "Android T", "Android U", "Android V", "Android W", "Android X",
             "Android Y", "Android Z"};
 ...  
   
 ....  


Next we will set data to the ListView using an ArrayAdapter class. Add following code to onCreate() Method.




     mListView = (ListView)findViewById(R.id.listView);  
   
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);  
     mListView.setAdapter(adapter);  
   

Here, we assigned the ListView that we declared in xml file to mListView. And then created an instance of an ArrayAdapter with the items we created before. ArrayAdapter acts as the man in the middle between the list and data. It inflates the Layout of each item and populates the defined data in the view.

Let's run the application.



We can see the list items populated in the ListView which is vertically scrollable. But when we select list items nothing happens. Let's add a click listener to the listView to add some actions to click event.


 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
       @Override  
       public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {  
         Toast.makeText(MainActivity.this, "You clicked :" + items[position], Toast.LENGTH_SHORT).show();  
       }  
     });  


We set the OnItemClickListener to the ListView where we override onItemClick method which will be called when any of the list item is selected. Which has position of the selected item as third argument. We can use that to display the selected item from our array.



When we run the app and press any list item we see a Toast message as seen on the screenshot above.

Find Full Source code of this example on GitHub


In the next tutorial we will see how we can use a custom adapter to display more complex data in a ListView.



Saturday, July 11, 2015

Layouts in Android

In this tutorial, we will have a look at different types of layouts in android. We will see how various layout attributes are set in order to arrange views in the screen. Let's begin with introduction to Layouts.





Layouts?

Layouts are used to define the arrangement of views in the screen. Mostly defined in XML, Layouts help us to build complex designs easily. We have different Layouts in android such as,


  • LinearLayout
  • RelativeLayout
  • FrameLayout
  • TableLayout


LinearLayout

As the name suggests LinearLayout is used for arranging views in linear fashion, either horizontally or vertically. Let's have a look at our Android Project that we created in previous tutorial.

Let's change the activity_main.xml file in res/layout folder to look like this.


 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"   
   android:orientation="vertical"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:paddingBottom="@dimen/activity_vertical_margin"   
   >  
   <TextView android:text="@string/hello_world"   
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <Button android:text="Click Me"   
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
 </LinearLayout>  


Here, we used LinearLayout to arrange a TextView and a Button vertically. In LinearLayout we defined android:orientation attribute to be vertical. We can change that to horizontal to align the views horizontally.






RelativeLayout

RelativeLayout can be used when we have to align the view in relative positions. The position of a View can be relative to another view or the parent View. Lets add a Linear Layout inside the LinreaLayout, so that our activity_main.xml becomes.


 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:orientation="vertical"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   >  
   <TextView android:text="@string/hello_world"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <Button android:text="Click Me"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <RelativeLayout  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content">  
     <TextView  
       android:id="@+id/text"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"   
       android:text="Let's learn Android APP development"/>  
     <Button  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:layout_below="@+id/text"  
       android:text="Get Started"/>  
   </RelativeLayout>  
 </LinearLayout>  


Here we used layout_below attribute to place Button below the Textview. Some of the major layout attributes that can be used to define positions are .

layout:toLeftOf
layout:toRightOf
layout:belowlayout:above
layout:alignParentTop
layout:alignParentBottom
layout:alignParentLeft
 layout:alignParentBottom









You may try these attributes and arrange the layouts in different way.

FrameLayout

FrameLayout is used when we have only one child view, FrameLayout holds only one view and expands it to entire screen area. It is helpful to arrange view in such a way that it scales properly in different screen sizes.

Now, let's add a FrameLayout below RelativeLayout.


 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:orientation="vertical"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   >  
   <TextView android:text="@string/hello_world"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <Button android:text="Click Me"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <RelativeLayout  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content">  
     <TextView  
       android:id="@+id/text"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:text="Let's learn Android APP development"/>  
     <Button  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:layout_below="@+id/text"  
       android:text="Get Started"/>  
   </RelativeLayout>  
   <FrameLayout  
     android:layout_width="match_parent"  
     android:layout_height="match_parent">  
     <ImageView  
       android:layout_width="match_parent"  
       android:layout_height="match_parent"  
       android:src="@drawable/headerbg"/>  
   </FrameLayout>  
 </LinearLayout>  


We used single View inside frameLayout, However we can also try adding multiple children to FrameLayout and align using layout:gravity attribute.

Table Layout

TableLayout is used to arrange the views in a tabular way in rows and columns. Let's try this code in our android_main.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:orientation="vertical"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   >  
   <TextView android:text="@string/hello_world"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <Button android:text="Click Me"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content" />  
   <RelativeLayout  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content">  
     <TextView  
       android:id="@+id/text"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:text="Let's learn Android APP development"/>  
     <Button  
       android:layout_width="wrap_content"  
       android:layout_height="wrap_content"  
       android:layout_below="@+id/text"  
       android:text="Get Started"/>  
   </RelativeLayout>  
 <TableLayout  
   android:layout_width="match_parent"  
   android:layout_height="wrap_content">  
   <TableRow  
     android:id="@+id/row1"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:padding="5dip" >  
     <TextView  
       android:id="@+id/text1"  
       android:text="Column 1" />  
     <Button  
       android:id="@+id/btn1"  
       android:text="Column 2" />  
     <Button  
       android:id="@+id/btn2"  
       android:text="Column 2" />  
   </TableRow>  
   <TableRow  
     android:id="@+id/row2"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:padding="5dip" >  
     <TextView  
       android:id="@+id/text2"  
       android:text="Column 1"/>  
     <Button  
       android:id="@+id/btn3"  
       android:text="Column 2"  
       android:layout_span="2"/>  
     <Button  
       android:id="@+id/btn4"  
       android:text="Column 2" />  
   </TableRow>  
 </TableLayout>  
 </LinearLayout>  


Here, we used TableLayout with TableRow element to define rows. We have two TableRow that makes a table with two rows.
We can also see Button on the second row has android:layout_span attribute to for defining the column span. The span value 2 makes the button span across two column as seen below.





We just saw different types of layouts. In the next tutorial we will see how we can organize various resources. 



Understanding Android Studio Project

We created android studio project in Getting Started tutorial . In this section we will have a look at anatomy of Android Studio project. 





Android Studio Project

If you have been following the previous tutorial you can see several folders in the project section of android studio. We will discuss about these folders in this section.




   This picture shows our Android project here we can see following folders,

1) manifest : This folder contains the AndroidManifest file.
AndroidManifest.xml


2) java : This folder will be the place for all the java code we write. Java code will be placed written under different packages as per the java coding conventions.

3)  res : This is were we keep all the resources required for the project. The resources may include images, xml layout files,  menu resources, dimension declarations, animation files etc.

4) gradle : this folder will include all the gradle scripts. We will learn more about gradle in this tutorial (Building android apps with Gradle).

Let's move to our next tutorial, Layouts in Android.

Getting Started


Getting Started




We will be using Android Studio as an IDE for our tutorials. In this tutorial I will assume that you already have setup Android Studio and updated android SDK to the latest version. We will be using AppCompat Library throughout the tutorials, so we will need those installed too.


When you launch Android studio you will see following welcome screen. Let's create new Android Studio project by selecting the 'Start a new Android Studio project' option in the Quick Start List.



Then in the next dialog enter Application Name , Package name and provide the project location, that's where  where you want to store your project.





In the next step, select the target android devices, We discuss about adding modules for Wear, TV, Auto and Glass, but for now Let's keep the default 'Phone and Tablet' selected. 

Select minimum SDK version, in this case 14. The minimum SDK version determines the lowest API level of Android that this app will run on.





Next, we select the activity template, We have different types of Activity Template which we can choose from but for this tutorial we will be using blank activity.





And, then in the final step of our project creation wizard, We can customize the Activity, For this tutorial we will keep the default values and click Finish. 

Then we have our Android Project ready, when the project opens we have following screen.





Now, if you Run the project you will see the screen as seen on the preview.




We will have a quick look at all the project elements in our next tutorial, Understanding the Android Studio Project.