Using Android SlidingDrawer

Remeber Android's old versions' (prior to 2.2) launcher screen where we had a sliding pane at the bottom that when dragged upwards displays the applications menu of the phone, that is called the SlidingDrawer control.


consider this layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
  <SlidingDrawer
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:id="@+id/drawer"
  android:handle="@+id/handle"
  android:content="@+id/content"
  >
  <ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/handle"
  android:src="@drawable/tray_handle_normal"
  />
  <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  android:id="@+id/content"
  >
  <TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="This is some text"
  android:id="@+id/txt"
  />
  <Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Click Me"
  android:id="@+id/btn"
  android:onClick="ClickHandler"
  />
  </LinearLayout>
  
  </SlidingDrawer>
</FrameLayout>



when the SlidingDrawer is pressed it looks like this:

the SlidingDrawer is a container that when dragged or pressed shows/hides its contents.

As the SlidingDrawer displays one content at a time, it must be declared within FrameLayout

the SlidingDrawer has two key properties:
android:handle: specifies the id of the control that acts as the handle.
android:content: specifies the id of the view that acts as content of the SlidingDrawer, most times will be a container.

you can open/close the drawer from the code like this:
if(drawer.isOpened())
    {
     drawer.close();
     btnToggle.setText("Open");
    }
    else
    {
     drawer.open();
     btnToggle.setText("Close");
    }

you can open/close the drawer with animation using these methods instead
drawer.animateClose();
drawer.animateOpen();

or you can handle the open/close operations automatically using toggle method:
drawer.toggle();
drawer.animateToggle();

you can lock/unlock the SlidingDrawer to enable/disable dragging or clicking of the drawer using these methods:
drawer.lock();
drawer.unlock();

Responding to SlidingDrawer Events:

SlidingDrawer has three key callbacks:
  1. when the drawer is open, handled by implementing OnDrawerOpenListener.
  2. when the drawer is close, handled by implementing OnDrawerCloseListener.
  3. when the drawer is close, handled by implementing OnDrawerScroll
    Listener.


drawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {
    
    @Override
    public void onDrawerOpened() {
     // TODO Auto-generated method stub
     TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
     txtStatus.setText("Opened");
     ImageView view=(ImageView)drawer.getHandle();
     view.setImageResource(R.drawable.tray_handle_selected);
     
    }
   });
         
         
                  
         drawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {
    
    @Override
    public void onDrawerClosed() {
     // TODO Auto-generated method stub
     TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
     txtStatus.setText("Closed");
     ImageView view=(ImageView)drawer.getHandle();
     view.setImageResource(R.drawable.tray_handle_normal);
    }
   });
         
         drawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {
    
    @Override
    public void onScrollStarted() {
     // TODO Auto-generated method stub
     TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
     txtStatus.setText("Scroll start");
     
    }
    
    @Override
    public void onScrollEnded() {
     // TODO Auto-generated method stub
     TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
     txtStatus.setText("Scroll end");
    }
   });

Notes:

Reactions: 

Using View Flipper in Android

Suppose you want to display a news bar in your activity. this news bar displays a single news item at a time then flips and shows next item and so on, then your choice would be Android's ViewFlipper.

ViewFlipper inherits from frame layout, so it displays a single view at a time.

consider this layout:
<?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"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
    <Button
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Flip"
    android:id="@+id/btn"
    android:onClick="ClickHandler"
    />
    <ViewFlipper
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:id="@+id/flip"
    >
    <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Item1"
    />
    <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Item2"
    />
    <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Item3"
    />
    </ViewFlipper>
</LinearLayout>


just a ViewFlipper container that contains three text views

now we want to flip the views when the button is clicked
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btn=(Button)findViewById(R.id.btn);
        flip=(ViewFlipper)findViewById(R.id.flip);
            
    }
    
    public void ClickHandler(View v)
    {
     
     flip.showNext();
     
    }

if we want to flip in reverese direction we could use
flip.showPrevious() instead

we can add animations to the child views when they appear or disappear:
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btn=(Button)findViewById(R.id.btn);
        flip=(ViewFlipper)findViewById(R.id.flip);
        //when a view is displayed
        flip.setInAnimation(this,android.R.anim.fade_in);
       //when a view disappears
     flip.setOutAnimation(this, android.R.anim.fade_out);     
    }

we can also set the ViewFlipper to flip views automatically when the button is clicked:
public void ClickHandler(View v)
    {
     
     
     //specify flipping interval
     flip.setFlipInterval(1000);
     flip.startFlipping();
    }

we can stop the flipping by calling flip.stopFlipping(); method.

or we can set the flipper to flip autommatically when the activity starts
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btn=(Button)findViewById(R.id.btn);
        flip=(ViewFlipper)findViewById(R.id.flip);
        flip.setInAnimation(this,android.R.anim.fade_in);
     flip.setOutAnimation(this, android.R.anim.fade_out);
     flip.setFlipInterval(1000);
     flip.setAutoStart(true);
     
    }

Reactions: 

Currency Converter v1.0 released on Slide ME

Currency Converter v1.0 is released and is available at this location:


the application provides real time currency convertion for more than 100 currencies.

provides the conversion rate of two currencies and the conversion of an amount of money from one currency to another.

download it for free and tell me what you think.

Reactions: 

Using Alerts in Android

In a previuos post we saw how to display a popup message using Toasts. Toasts are just notification messages involving no interaction from the user.

another way to show interactive messages is to use Alerts. alerts act as MessageBox or JOptionPane in J2SE. they have buttons that can be used to take decisions.

Creating Alerts

let's check this example to create an alert and show it:
//declared as final to be able to reference it in inner class declartations of the handlers 
     final AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("Alert Dialog");
     builder.setMessage("This is the alert's body");
     builder.setIcon(android.R.drawable.ic_dialog_alert);
     
     builder.setPositiveButton("OK", new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText("You clicked Ok");
   }
  });
     
     builder.setNegativeButton("Cancel", new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText("You clicked Cancel");
   }
  });
     
     builder.setNeutralButton("Do something", new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText("Neutral Button Clicked");
    AlertDialog ad=builder.create();
    ad.cancel();
   }
  });
     
     builder.setOnCancelListener(new OnCancelListener() {
   
   @Override
   public void onCancel(DialogInterface dialog) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(txt.getText()+" the cancel listner invoked");
   }
  });
     
     
     
     builder.show();

the previous code displays the following Alert

the code may look bulky but it's very simple.
first we create an instance of AlertDialog.Builder. we use the builder object to construct the AlertDialog object.
we specify the title and the icon of the alert. then the text to display in the body of the message.
the AlertDialog can display up to three buttons:
positive button: represents the OK button.
Negative button: represents the cancel button.
Neutral button: represents a button to perform another functionality other than ok or cancel.

note that there are no restrictions on the use of the three buttons, they can perform the same functionality the difference is just in logical meaning. but the three buttons cause the Alert dialog to dismiss.

we then specify the text and the click handler of each button.
in the neatral button click handler we added the lines AlertDialog ad=builder.create(); and ad.cancel();. the firt line gets a reference to the current dialog created by the builder to provide additional functionality such as invoking cancel() method.

the cancel method raises the onCancel callbcak method.

we could have replaced the previous code with the following:
AlertDialog ad=builder.create();
     ad.setMessage(message);
     ad.setIcon(icon);
     ad.setMessage(message);
     ad.setButton(text, listener);
       .
       .
       .

Displaying Custom Views:

alerts can display complex views rather than simple text messages. create an xml layout file called alertview.xml 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:id="@+id/toastView"
    android:background="#DAAA"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Hello alerts"
    android:textColor="#000"
    />
    
   <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/txtDate"
    android:textColor="#000"
    />
    <Button
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/btnAlert"
    android:text="Click"
    />
</LinearLayout>



to display this view as the alert view we do it like this:
View bodyView=getLayoutInflater().inflate(R.layout.alertview, (ViewGroup)findViewById(R.id.toastView));
     
     
     TextView txtDate=(TextView)bodyView.findViewById(R.id.txtDate);
     txtDate.setText(Calendar.getInstance().getTime().toLocaleString());
     Button btnAlert=(Button)bodyView.findViewById(R.id.btnAlert);
     btnAlert.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    TextView txtDate=(TextView)bodyView.findViewById(R.id.txtDate);
       txtDate.setText(Calendar.getInstance().getTime().toLocaleString());
       TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(Calendar.getInstance().getTime().toLocaleString());
   }
  });
     builder.setView(bodyView);
       .
       .
       .

what is interesting in this approach is that the alert is fully interactive, by clicking the button you can change the value of any view in the alert or in the activity.

you can also set the title of hte alert to be a custom view via builder.setCustomTitle(View v) method in the same way described above.

Displaying an alert of items:

alerts can display a list of items from which the user selects from like this:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"};
     AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("Items alert");
     
     builder.setItems(items, new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(items[which]);
   }
  });
     
     builder.show();
this will display an alert like this:

notice that we do not have to specify any buttons because when the user clicks on any item the alert will be dismissed.

if the list items are in an Adapter we can achieve the same result using builder.setAdapter(Adapter ad,OnClickListener listner) method:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"};
     ArrayAdapter arr=new ArrayAdapter(this, android.R.layout.select_dialog_item,items);
     
     AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("Adapter alert");
     
     builder.setAdapter(arr, new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(items[which]);
   }
  });

or if the items are returned from a database in a cursor we can use
builder.setCursor(Cursor cursor, OnClickListener listner, String labelColumn)

Displaying alerts with items with choices:

we can add items to the alert with choices whether they are single choice (Radio buttons) or multiple choices (Check boxes).

to display single choice items:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"};
     AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("List alert");
     builder.setSingleChoiceItems(items, 0, new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(items[which]);
   }
  });
     builder.setPositiveButton("OK", new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    
   }
  });
     builder.show();

the second parameter of setSingleChoiceItems is an integer specifying the index of the selected item

notice that we added a postive button that when clicked dismisses the alert cause unlike the regular items list the alert won't be dismissed when an item is selected.

the builder.setSingleChoiceItems method has other overloads that can accept an Adapter or a Cursor as parameters that hold the items to be displayed

to display multiple choice items:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"};
     AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("List alert");
     builder.setMultiChoiceItems(items, null, new OnMultiChoiceClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which, boolean isChecked) {
    // TODO Auto-generated method stub
    TextView txt=(TextView)findViewById(R.id.txt);
    txt.setText(txt.getText()+" "+items[which]);
   }
  });
     builder.setPositiveButton("OK", new OnClickListener() {
   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    
   }
  });
     builder.show();

the second parameter of setMultiChoiceItems is an array of boolean values specifying which items are set selected. if you want no items to be selected then set it to null, otherwise specify an array with the same length of the items with boolean values indicating which item is selected and which is not like this:
new boolean[] {true,false,...}

works in the fashion as single items choice except that the selection here is multiple.

download a demo applications on alerts from here

Reactions: