Share the ideas and thoughts, become united ...
Showing posts with label custom. Show all posts
Showing posts with label custom. Show all posts

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.

Saturday, December 19, 2009

Raise the desired event in java - it's possible and easy

I, myself is a beginner in programming languages. So, i encounter problem now and then. Recently i have faced a very interesting problem. As you know it is pretty much easy in C# to raise the desire event (or you don't know). But i was wondering how to do it in JAVA. Well i found it pretty much amazingly easy !!!

you just have to call dispatchEvent(AWTEvent e).

Explanation : This method takes the event that you want to raise and dispatches it (handles it).

Sample Code:

public class MainWindow extends JFrame implements WindowListener {
/* properties + methods */
public MainWindow() {
// bla bla codes
this.addWindowListener(this); // i am listening this window and the event handler is also def. in this class
// more codes
}
public void windowClosing(WindowEvent e) { // an event handler
// codes ...
System.out.println("dude this window is closing... save it.."); // code i am going to execute
// and still coding
}
public void raiseWindowCloseEvnt() { // user def. fn to raise the event
// last words before you close your window :)
this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); // will i am dispatching a new event which is associated with this window (via this pointer). and i am likely to raise the Window_Closing event. Now i can raise the event just by calling this function.
}
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.setVisible(true);
mw.raiseWindowCloseEvnt(); // see the output console :D
}
}

Pretty much easy isn't it? :)