Search This Blog

Thursday, December 31, 2009

Android ViewFlipper and SlidingDrawer

In my last post i talked about android selector mechanism and how to customize default GUI components apperances. another issue with mobile phone applications is limited displaying space, i mean if your application wants to go a bit further than a basic , simple application, it is almost gonna be impossible to fit all GUI options and features in a relatively small displaying space of mobile phones.

as we've already talked about it, the first option to solve this sort of problems is Menus and dialogs which are pretty easy to use and simple, but what if you need something more than that with higher level of customizability, that's when ViewFlipper and SlidingDrawer come into play(although they could be used for other purposes as well), like menus and dialogs they enable us to have some views hidden and show them when they are requested or when it's appropriate.
I'm gonna add a ViewFlipper and SlidingDrawer to my last application.

first of all let's see what a ViewFlipper is, ViewFlipper is Actually a View container which can hold different Views, but it shows just one of those Views at a time and hide others, you can switch between views manually or automatically, most interesting thing about ViewFlipper is that it uses two different Animations for flipping between views, one is used for outgoing View and the other one for incoming View.
OK, here are some snapshots of what we are trying to achieve using a ViewFlipper:









There are two views between which we wanna flip, a ListView (Which we talked about it last time) and a simple view with a text and a button on it, When we press "Next" button our ListView will slide out and the other view will slide in and when "Go Back" button is pressed two views will be switched again.
our XML will be something like this :




<ViewFlipper android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">


<FrameLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="50dip">

<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:dividerHeight="0dip"
android:divider="@null"
android:listSelector="@drawable/list_selector"
android:layout_gravity="center" />

</FrameLayout>


<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/wood01"
android:padding="20dip"
android:layout_gravity="top"
android:layout_marginTop="50dip">

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TEST"
android:layout_gravity="center"
android:padding="15dip"
android:textSize="22dip"
android:textColor="@color/white" />

<Button android:text="Go Back"
android:id="@+id/back_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />


</LinearLayout>



</ViewFlipper>





As you can see our ViewFlipper has two children, a FrameLayout containing the ListView and a LinearLayout containing a TextView and a Button. by default the first child is shown when application comes up for the first time.
setting Animation for our flipper is pretty easy and straigh forward, here's the code I've used :




this.flipper = (ViewFlipper)findViewById(R.id.flipper);

Animation s_in = AnimationUtils.loadAnimation(this, R.anim.slidein);
Animation s_out = AnimationUtils.loadAnimation(this, R.anim.slideout);
this.flipper.setInAnimation(s_in);
this.flipper.setOutAnimation(s_out);




and here are the content of slidein.xml and slideout.xml respectively :




<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">

<translate android:fromXDelta="-100%" android:toXDelta="0%" android:duration="1800" />

</set>







<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">

<translate android:fromXDelta="0%" android:toXDelta="100%" android:duration="1800" />

</set>




All you need to do to switch the showing view manually is to use showNext() and showPrevious() methods of ViewFlipper class.
Another predefined Widget for hiding stuff is SlidingDrawer and its name pretty much suggests what it does. what does a drawer do!? it has a handle which is used to drag the drawer container out...obviously ;)
I added a simple SlidingDrawer to my application and you can see how it looks like below :












First of all, I should say sorry for this wierd object I used for my drawer's handle ;) I couldn't find anything better!!
here is the XML which is being used to create what you saw above:




<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="230dip"
android:id="@+id/frameLayout"
android:layout_gravity="bottom">

<SlidingDrawer android:layout_height="wrap_content"
android:handle="@+id/handle"
android:content="@+id/content"
android:id="@+id/slide"
android:orientation="vertical"
android:layout_width="fill_parent">


<ImageView android:layout_width="55dip"
android:layout_height="55dip"
android:id="@id/handle"
android:src="@drawable/arrow" />


<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@id/content"
android:orientation="vertical"
android:background="@drawable/wood01"
android:padding="10dip">

<Button android:text="Test1"
android:id="@+id/Button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<Button android:text="Test2"
android:id="@+id/Button02"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<Button android:text="Test3"
android:id="@+id/Button03"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />


</LinearLayout>
</SlidingDrawer>
</FrameLayout>





SlidingDrawer tag has two important attributes, android:handle and android:content; these attributes are actually references to other views which will be rendered as our drawer's handle and content. as you can see here we have two child views with the same id as specified for android:handle and android:content.

That's it. we are now familiar with two other useful Android widgets...

Wednesday, December 30, 2009

Android Selectors

GUI is always an important part of any application, because ordinary users dont know and don't care what's behind the scene; they want something easy to work with and nowadays attractive GUI is a must for most applications. although making an appealing and innovative interface needs something more than just programming skills and knowledge, every programmer should know how to customize different GUI components within whatever framework and environment they are working.
Today I'm gonna talk about one of the beautiful features of Android which gives you the ability to change the default behavior of GUI components.
when designing GUIs, most of the times you want to change the appearance of buttons, input Fields, menus and.... Android Selectors have been provided to solve all these kind of problems, they enable us to decide what to show and how to show based on different states of each components...for example you can tell a button to have black background color with red text color when it is in pressed state or whatever else.
In this post i will show you an example of customizing a ListView which is gonna look like this :













It is nothing but a simple ListView... believe me, and here is the XML which is being used to create it :




<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:dividerHeight="0dip"
android:divider="@null"
android:listSelector="@drawable/list_selector"
android:layout_gravity="center" />





the code which I've used to populate the list :




ListView view = (ListView)findViewById(R.id.list);
view.setAdapter(new ArrayAdapter(this, R.layout.menu_item, ITEMS));
view.setOnItemClickListener(this);




and finally, here is the content of menu_item.xml file :



<?xml version="1.0" encoding="utf-8"?>:


<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12dip"
android:textStyle="bold"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:layout_gravity="center"
android:gravity="center"
android:background="@drawable/selector"
android:textColor="@drawable/color_selector"/>:






see? it's a simple, ordinary list, there is no secret here but a simple trick; I've used selectors for both background and text color for our TextView, what do you think "selector" and "color_selector" are?
they actually refer to selector.xml and color_selector.xml files inside drawable directory, you can see the content of them below :





<selector xmlns:android="http://schemas.android.com/apk/res/android">:
<item android:state_selected="true" android:drawable="@drawable/selector_s" />:
<item android:state_pressed="true" android:drawable="@drawable/selector_s" />:
<item android:drawable="@drawable/selector_d" />:
</selector>:









<selector xmlns:android="http://schemas.android.com/apk/res/android">:
<item android:state_selected="true" android:color="@color/black" />:
<item android:state_pressed="true" android:color="@color/red" />:
<item android:color="@color/white" />:
</selector>:





what does the content of color_selector file mean? it says that the text color will be black in "selected" state, red in "pressed" state and white otherwise, and i reckon now you should be able to figure out what the content of selector file means.
here is the content of selector_s and selector_d :



<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/pill"
android:gravity="center" />





<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/pill_s"
android:gravity="center" />



as you might have noticed,I've also used "listSelector" attribute of our ListView to customize the behavior of the list when user is going through options in the list.
list_selector.xml file looks like this :




<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/wood01" />
<item android:drawable="@drawable/wood02" />
</selector>




and here are all the drawable objects i used in this application if you wanna give it a try and see how easy it works ;)




















Sunday, December 20, 2009

Watch out your background thread!

The other day i came across something that i hadn't known before , do you
know that when you flip your android phone and go from portrait mode to landscape or vice versa, whatever application is running will be killed by android and recreated again?
It wouldn't be a problem as long as lifeCycle methods of your activity are implemented well, but what if you have a seperate thread which is working behind the scene and interact with your activity through a Handler, like what I have used in both WhitePage and YahooSearch applications. what happens? if you switch the screen mode while our Thread is working the activity is killed, but our Thread is abviously not notified about what has happend, so it will send the message through the old handler to the old activity which might be waiting for Garbage Collection or whatever else but it is not the activity which you wanted to send your message to.
so I've come up with this solution, I override onSaveInstanceState() method of activity class, it checks whether there is any unfinished task running, if so it locks the thread and save it, we also need to check if there is any saved thread in onCreate() method and unblock it with a new Handler class so that Messages will be delivered through the right Handler.(NOTE : we can also use onRetainNonConfigurationInstance() and getLastNonConfigurationInstance() methods which is apparently a better approach to solve this particular problem. ***Please see comments on this Post*** )




@Override
public void onCreate(Bundle savedInstanceState) {
.
.
.

if(savedInstanceState != null){
this.thread = (FetcherThread)savedInstanceState.getSerializable("thread");
this.thread.unlockIt(handler);
}
else{
this.thread = new FetcherThread(handler);
this.thread.start();
}

.
.
.

}

@Override
public void onSaveInstanceState(Bundle bundle){
super.onSaveInstanceState(bundle);
if(!this.thread.lastRequest_finished)
this.thread.lockIt();

bundle.putSerializable("thread", this.thread);
}





On the other side, in our Thread I added a new flag which is checked just before the thread wants to send a message back, if everything is alright it carries on and send a message, otherwise it will wait until it's notified that it is safe to send a message.




public void run(){

.
.
.

Bundle content = new Bundle();
content.putSerializable("result",results);
Message msg = new Message();
msg.setData(content);


while(!this.launcherReady){

try{
synchronized (this) {
this.wait();
}
}catch(InterruptedException exp){
////Just Nothing
}
}

this.callback.sendMessage(msg);

.
.
.

}



public synchronized void lockIt(){
this.launcherReady = false;
}

public synchronized void unlockIt(Handler newOne){
this.launcherReady = true;
if(newOne != null)
this.callback = newOne;
this.notifyAll();
}





you can also use Android AsyncTask class when you need a background task, which is a neat way to do it (if you will) , but be aware of the fact that it does not support the issue we discussed here by default. so you will still need to somehow handle it by yourself.

Saturday, December 19, 2009

When Android takes me beyond the time!!!

To be honest I cannot get this question out of my mind that what's gonna happen in future? i mean how do you envision our future? if you had asked someone(even a computer professional) about the future of internet and web just 15 years ago, they would have probably had no idea how powerful it was going to be. It is so funny but sometimes i have a feeling as if internet has always been around, i cannot remember what we used to do without internet back then.
Actually I believe the concept of computer is somehow getting mature, The first period was the wave of modern Operating Systems and the concept of GUI, say since early 80s till mid 90s; The second Wave was internet and the concept of remote services, roughly since mid 90s till now. and when you look around yourself you can smell the third wave, it has already begun...Mobile phones are no longer just a simple phone, you hear something like 1Ghz processor mobile phones with 256Mb Ram and you remember just 10 years ago when you were bragging about your new pentium3 PC which was just 600Mhz and you were lucky if you had 256 RAM!!!
and more importantly when you are coding using Android API and somehow get involved with this mobile application industry, you sometimes see something that was not more than a dream and fantasy just 5 years ago... but not anymore.

I envision a future in which ordinary computer users wouldn't need a big PC (by PC I mean any kind of Personal Computer regardless of its OS) or Laptop to get what they want, all they need would be achievable using their mobile phones, and nobody will even bother themselves to use these boring, old-fashion devices unless you are a professional user or you might say a gamer ;) .
But what's gonna happen for pc? Will it just die out? I dont think so....I think we will see a revolution! When smart phones are able to do what a PC can, it is a sign that something should get changed...step up time.
But how? I bet you ,like anyone else i know, use your computer mostly to get different types of remote services either web-based or not....it means GUI and Remote services are paying off, but it is so heavy weight, have you ever felt this? actually we're all feeling that and that's why we go and buy ourselves a smart phone; checking your email, chatting with your friends, Twitter, Facebook, Flicker ,Google maps , GPS applications, Bluetooth applications, taking high quality pictures, recording video, browsing through web and you can also give a call to a friend if it is necessary...all of these services and capabilities with a device as big as your palm...and that is what I'd like to call it Technology Transparency...if the first wave was the concept of GUI and Human computer interaction and the second one was Web and Remote services ,I would say the third one is the concept of Mobility and Technology Transparency.
Users by no means want to get dependent or limited, they want to get what they want whenever, wherever without any hassle, and that's why we need wireless communication...nobody is willing to figure out which wire should go where or what is the difference between this and that kind of sockets....and that is the reason behind Wireless sensor networks, we want to use some tiny sensors and just chuck them somewhere and without any configuration or any hassle they start serving us...and that is why we love smart phones, we don’t like to have to go to some particular place to get access to some basic services, we just want to pull our phone out of our pocket ,of course a touch screen one because button is not transparent enough!!, and get what we want... boundless and transparent services.

when you analyse all these facts you get the impression that Chrome OS concept is a pretty possible candidate for future PCs, current PCs structure and Their operating systems are too difficult to deal with and a real headache for ordinary users who want to get some benefit out of it as fast and transparent as possible, having said that and taking account of this fact that high speed internet connections are becoming available for anyone and thank to Web2.0(which is a good example of Technology Transparency itself) many software giants have started or at least have been considering to provide an online versions of their products which means you would no longer need to have a Microsoft office, Adobe reader or Winamp installed on your local computer, although you might need them on you mobile phone and could have them installed there...
Fair enough, so you will not need a HD when you don’t want to install any software unless you need to store something, interestingly enough there are already some web-based services which allow you to store your stuff. all these things means that you would be able to get rid of your old-fashion OS (specially because you are already dealing with one on your mobile phone) and your HD and any hassle related to them such as organizing issues and security issues and let it to be taken care of by someone else(Transparently).
all you will need is a high speed connection and a OS which works as a gateway between your computer and infinite online services out there, I also think we will need something more than web and html, we will need some layer on top of web or at least beside it to make the whole thing more smooth and accessible (I mean Transparent ;) ).
That’s how I envision our future and what i call it Mobility and Technology Transparency wave. What’s your thought? How do you envision our future? and why?







Friday, December 18, 2009

WhitePage Application_Adding a new contact in Android 2.0

Actually i was gonna talk about HTML parsing mechanism which i used for my Whitepages application,but i thought it wouldn't be such a good idea to talk about it on this weblog since it has nothing to do with android and I just did it to fulfill my curiosity. the only thing we need to know is how to make our query which in this case was a simple GET query and then identify how data is wrapped inside HTML tags which can be easily done thanks to FireBug plugin, the rest will be some effort to figure out a good algorithm to extract data from HTML document as efficient as possible...
What i would like to talk about in this post is Contacts in android and how to add a new Contact to Android's Contact List. Initially i thought it was gonna be a simple thing to do but i gotta admit it, it was the first time i felt
a bit confused since I started android development. what happened was i wanted to write a piece of code to add a new contact when user selects one of our application menu options, I went to Android developers website(like i usually do) to find some clues on how to do that... as you might have already noticed there are some examples in Content Providers section about how to work with Contacts using People class, good, i was pretty sure that i got it... but when i started coding,Eclipse warned me that People class was deprecated... Beautiful!!!so what am i supposed to do if i shouldn't use People class, I was thinking with myself... having a look at People class documentation I found out that it's been replaced by a totally different mechanism and we should use another class called ContractsContact to interact with Contacts...
one of the things that struck me was the fact that there are more than two dozens classes and interfaces in android.provider package marked as deprecated and a completely different approach has been introduced for interacting with contracts since API level 5. this new API gives you a great level of flexibility and extensibility but as we all know everything has a price, if you want a flexible and extensible framework, no worries, but it comes with a bit more complexity, and I think it could be why they still prefer to stick with People class examples... ;)
Fair enough, here is the code that i used in our application to add a new Contact according to what user has already selected :



try{


ArrayList op_list = new ArrayList();
int backRefIndex = 0;
op_list.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, null)
.withValue(RawContacts.ACCOUNT_NAME, null)
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, this.selectedItem.getName())
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(StructuredPostal.FORMATTED_ADDRESS, this.selectedItem.getAddress())
.build());

op_list.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, backRefIndex)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, this.selectedItem.getPhone())
.withValue(Phone.TYPE, Phone.TYPE_HOME)
.withValue(Phone.LABEL, "")
.build());

ContentProviderResult[] result = getContentResolver().applyBatch(ContactsContract.AUTHORITY, op_list);


}catch(OperationApplicationException exp){

exp.printStackTrace();

}catch(RemoteException exp){

exp.printStackTrace();
}



dont freak out ;) , although it might seem quite different than what you are familiar with, it's mostly because i used Batch insert technique and ContentProviderOperation.Builder class which have been introduced in API level 5.
you can still use getContentResolver().insert() and ContentValue objects but it is recommended to use new batch technique over traditional insert and update method.
what is important here is that you first need to create a RawContact and then use its ID to add some data like name, phone number and address, in traditional method you would need to insert a RawContact, get its ID and then use that ID in subsequent operations, I used withValueBackReference() method here which has been provided for handling these sort of cases when you are using batch technique.
You can find some good information about this whole thing in Data class documentation.








Sunday, December 13, 2009

WhitePage Application_Part 2

In my last post we saw how the main page of our application works, in this post we will be discussing some other features of our application. if you remember, the result of our search is shown in a page like this:





I've used ListView for this page and here is our layout file for this page :



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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/resultLayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="true"
android:background="@color/black"
android:layout_margin="2dip"
android:scrollbars="horizontal">


<ListView android:text=" text "
android:id="@+id/listView"
android:minWidth="70dip"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:padding="5dip"
android:divider="@color/white"
android:dividerHeight="10dip"/>






</LinearLayout>

</LinearLayout>



it's pretty simple,isn't it? what we need to know is how to tell to a ListView to show whatever we want to show and and how to format it. in our case after each search we will have an array of Result class, Result objects are simple POJOs which have a name, address and a phone number,we also want to show our result is three different lines(you might need to show an image in each row or have a more complicated structure for each row).
ListView uses something called ListAdapter to get all data needed to be shown and know how to show it, there are some predefined subclasses of ListAdapter such as ArrayAdapter, CursorAdapter and SimpleAdapter which provide some convenient methods for interacting with data for some frequently used mechanisms such as XML Documents or Database.
We can also customize these Adapters by simply inheriting from them and extending their behavior and that's what I've done here.
you can see our extended Adapter below :



private class MyAdapter extends ArrayAdapter {

private Activity context;

public MyAdapter(Result[] items){
super(MainActivity.this, R.layout.item,items);
this.context = MainActivity.this;
}

@Override
public View getView(int position,View convertView,ViewGroup parent){

LayoutInflater inflater= this.context.getLayoutInflater();
View row=inflater.inflate(R.layout.item, null);

TextView name = (TextView)row.findViewById(R.id.name);
TextView loc = (TextView)row.findViewById(R.id.location);
TextView phone = (TextView)row.findViewById(R.id.phone);

Result temp = (Result)getItem(position);

name.setText(temp.getName());
loc.setText(temp.getAddress());
phone.setText(temp.getPhone());

return row;
}

}




getView() method is our key method here, it is sent the position of a row in ListView and it's responsible to return a View Object representing that row which will be shown by ListView later. it is really cool because you can use
a View object and it means that you will be able to literally do whatever you want, i mean it would give you a great opportunity over how much you can customize your rows in ListViews.(we forget some basic concepts of OOP sometimes,
or should i say we underestimate how significant they could be, one of these basic concepts is Polymorphism...just look how nice it works here.... anyway just thought it'd be worthwhile to mention it ;) ).

Like any other View Objects we've created so far we can either use XML layout file or just hard code it. i used the first approach here, my layout file's name is item.xml and it looks like this :



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




<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:layout_marginTop="5dip"
android:layout_gravity="left"
android:layout_width="wrap_content">

<TextView android:text="Name"
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70dip"/>

<TextView android:text="Location"
android:id="@+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70dip"/>

<TextView android:text="PhoneNumber"
android:id="@+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70dip"/>


</LinearLayout>


</LinearLayout>



OK, let's get back to our getView() method that might seem a bit confusing....but it's not, believe me ;) .
all we need to do is to convert our layout file into a View Object, actually it's not a new thing...it's done in our all application but behind the scene. All we need to do is to get an instance of LayoutInflater object using getLayoutInfalter() method of Context class (Our Activity) and call inflate() method.once we have our view we can get the Result Object in that position and then fill our Textviews with appropriate data.

remember that each time that user does a search and there is any Result for that search we use the following code to renew our data in ListView :

listview.setAdapter(new MyAdapter(results));


I'm not sure whether it's a good way to do this though. ;)

The last thing I'm gonna talk about is menus and how to use them in our applications. we've got a menu with three options in our application but two options must be disabled unless we are in Result page, if user presses their phone menu button they will see something like this depending on which page they are currently in :











to achieve this we need to override three methods of Activity class which you can see below :




@Override
public boolean onCreateOptionsMenu(Menu menu) {

menu.add(0, 1, 0, "Show Saved entries");
menu.add(0, 2, 0, "Add to my contacts");
menu.add(0,3,0,"Save this entry");
return true;

}

@Override
public boolean onPrepareOptionsMenu(Menu menu){
//menu items are disable when we are in the main page...
for(int i=1;i<3;i++){
menu.getItem(i).setEnabled(!this.main);
}

return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item){

int id = item.getItemId();
this.selectedItem = (Result)view.getSelectedItem();

switch(id){

case 1 : showSavedData();
break;
case 2 : addToContact();
break;
case 3 : saveItem();
break;

default : assert false : "Invalid Options!";

}

return true;
}





I also want to have another menu which shows our options when user clicks on one of our result items in ViewList, we would need to be able to get notified when an item is clicked, ListView class has a setOnItemClickedListener() method which gets an instance of OnItemClickListener class this class has a callback method named onItemClicked(), you can see my implementation of this method here :



public void onItemClick(AdapterView adapter, View arg1, int position, long arg3) {

CharSequence[] options = {"ADD TO CONTACTS","SAVE THIS ENTRY"};

this.selectedItem = (Result)adapter.getItemAtPosition(position);

if(this.resultOptions == null){
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Options");
builder.setItems(options, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub

if(which == 0)
addToContact();
else
saveItem();

dialog.cancel();
}
});

this.resultOptions = builder.create();
}

this.resultOptions.show();

}



so when user clicks on any item they will be shown something like this :






I will talk about WhitePageExtractor class that has been used to extract our data from www.whitepages.com.au and also I'm gonna figure out how to work with phone contacts and add a new contact in my next post...