Share the ideas and thoughts, become united ...

Wednesday, March 27, 2013

Android: Custom ListView


Android provides a rich development environment for the developers. It has many widgets built in which can satisfy the needs of the developer. Even if those element cannot full fill developer's requirements; they can still be easily extended to fit the requirement.

One such example would be the Custom ListView. Android provides ListView element to display items in a vertical scrolling list. User can navigate through that list and can perform action such as Tap, Long Tap or double Tap.

But what if we need to change the default list view? What if we need to add custom element into the view along with the text? This can be easily achieved through extending the Adapter class in android.

One popular Adapter type is ArrayAdapter which can be extended to provide custom view to the list view.

You can think the Adapter class as the Content Provider for the list view. Every listview has an associated Adapter which provides data to populate it's view. If the ListView requires to display a item on it's list, it asks the Adapter to fill it's view for that position. Adapter then fill up the view and return the view to the list view. That view is shown to the user.

So lets get down to business !!!

You will need to define two layout xml for your custom layout. Because the layout works like just below -


So, Generally ListView will reside in the main.xml which is our view for this Activity.
And rowlayout.xml will be used by our extended ArrayAdapter to populate and return a single row element in the list whenever the list asks for it.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/countryLV"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </ListView>

</LinearLayout>

And our row element layout -

rowlayout.xml
 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/imgV"
        android:maxWidth="100dip"
        android:maxHeight="75dip"
        android:layout_width="100dip"
        android:layout_height="75dip"
    />
    <LinearLayout
        xmlns:andxmlns="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    >
        <TextView
            android:id="@+id/txtV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="40px"
            android:textStyle="bold"
        />
        <TextView
            android:id="@+id/txtVDescription"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="20px"
            android:textStyle="italic"
        />
    </LinearLayout>
</LinearLayout>

 Important lines are marked red with underline to highlight them. Most of them are under "android:id" tag, this tag is used to reference back to this element in java code.

Thing to notice is how the layout is formed, First we took a horizontal layout, this way our elements will be added horizontally. Then we add our image, which will be left of our row. Next again we add a vertical layout; this ensures the addition of two text elements will be arranged vertically just beside the image.

Next is our Java Code, we need two classes. One is our version of ArrayAdapter and another is the actual Activity class.

First our version of ArrayAdapter

MySimpleAdapter.java
public class MySimpleAdapter extends ArrayAdapter<String>{

    private final Context context;
    private final String [] values;
    public MySimpleAdapter(Context context,    String [] values) {
        super(context, R.layout.rowlayout, values);
        this.context = context;
        this.values = values;
    }
   
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View myView = inflater.inflate(R.layout.rowlayout, parent, false);
        TextView tView = (TextView)myView.findViewById(R.id.txtV);
        TextView tVD = (TextView)myView.findViewById(R.id.txtVDescription);
        tVD.setText(values[position]);
        ImageView imgView = (ImageView) myView.findViewById(R.id.imgV);
        tView.setText(values[position]);
        imgView.setImageResource(R.drawable.icon);
        return myView;
       
    }

}

As you can see that our Adapter class extends the ArrayAdapter<String>. We passed the elements in the constructor of this class which is again passed to the super class.

The most important function to override is the getView method. Whenever the list view wants to populate its view, it will ask our adapter through this method. In this method we inflate a view based on row layout and fill up the elements in it. And then return the inflated view. This view is then shown by the listview element. 2nd parameter of this method, convertView, is used to recycle the view. But we left it for simplicity.

Last class will be our actual activity -

ListViewLearn2Activity.java
public class ListViewLearn2Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ListView lv = (ListView) findViewById(R.id.countryLV);
        String[] values = new String[] { "Item1", "Item2", "Item3", "Item4", "Item5", "Item6",
                "Item7", "Item8", "Item9", "Item10", "Item11", "Item12"};
        MySimpleAdapter adapter = new MySimpleAdapter(this, values);
        lv.setAdapter(adapter);      
    }
}

Trivial stuffs here.
So, this concludes the demonstration of how easily you can create your own custom list view in android.

Let me know your thoughts.

Download entire project here.

Friday, October 19, 2012

Implicitly linking DLL with VS2010 or earlier

You may be wondering what is "Implicit DLL linking". There are two way to link to a DLL one is "Implicit" another one is "explicit".
When you are the builder of the DLL or you have the exported symbol definition file or the exported lib, you can add the DLL simply by incorporating the .DEF (definition file) or the .lib file to the project properties.
But when you do not have the any of the things mentioned above, you have to load the DLL explicitly by using "LoadLibrary" win32 API, get the function pointer by calling "GetProcAddress" and the calling the function using the function pointer.
Today I am going to discuss how to "Implicit" link DLL file into your application.
First open a DLL project - usually a win32 project.

win32 DLL project window

Then select DLL from the next window to open the project as a DLL project.
Next I am going to add a header file called Math.h and add some basic function there. which I will export through DLL and use it in a console application.
the Math.h file
#pragma once
class __declspec(dllexport) Math {
public:
    int add(int a, int b);
    double sqr(double a);
}
and the cpp file
#include "Math.h"
int Math::add(int a, int b) {
    return (a+b);
}
double Math::sqr(double a) {
    return (a*a);
}
__declspec(dllexport) will tell the compiler that this class should be exported by the DLL for use in application.
Building this project will generate two components.
1. the DLL file itselfv [myDLL.dll]
2. a lib file which holds the necessary stubs and initializations to call appropriate DLL function  [myDLL.lib]
to incorporate DLL into an application one has to include the .lib into project dependencies.


Thats all. Now you can build your application and use the DLL function very easily.
Hope this helps.
If you have any queries or suggestions, please leave a comment.

Sunday, April 8, 2012

Optimizing the Code ... Optimizing the Solution

Sometimes developers are over excited about creating an optimized solution by optimizing & refactoring the code. They try to optimize every bit and line to their heart's content. Optimization is an art, but sometimes you gotta admit that overdoing any art, loses it's beauty. So, what optimization process should be followed? Well, I want to share my view on that matter.

Create a solution but don't bother about the "Perfect solution" 
          What good a highly optimized, well written & well maintained code base can do, when it can not solve the problem? The simple answer is nothing. Every solution is written so that it could solve a problem. If you are given a non working but nicely written application will you choose it over a badly coded working solution? I guess, you got the point.

Optimize the solution but never over do it 
          Then next state would be optimize the solution. After you have a solution you can make it more better. Break the function into small functions. Group the class into a module. Apply DP where appropriate.

The 90 - 10 rule
          Try to optimize the section which consumes most of the time. The 90 - 10 rule follows as -  10% of code constitutes 90% of total running time of the application. Have you ever think of any solution not having a loop? Have you seen a complex algorithm not having several loops? These loops are the CPU cycle hogger. They are the 10% out of 100% code. Try to optimize that 10% before optimizing other sections. Slight improvement over that 10% will leave a mark on the performance of your application.

Thank you for reading.