Monthly Archives: April 2013

PopupMenu Demo

The PopupMenu is anchored to a View. If a PopupMenu is shown in response to a click event to a button, the Popup will be displayed under the button if there is room.
The PopupMenu needs at least SDK 11. You need to open “AndroidManifest.xml” and change the minimum SDK version (“8″) to “11” since the ADT makes an app template with “8” for the minSdkVersion.

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="17" />

Just like any other Android API Guides, the section of the PopupMenu (http://developer.android.com/guide/topics/ui/menus.html#PopupMenu) is good for just lying-down-readers for fun but not good enough for someones who really need to use it.

Here I would like to provide a complete tutorial. But notice that this is not something that you can copy and paste it to build. You have to understand what you are doing.

First let us add a button to show a Popup menu. Please notice that the android:onClick attribute has the “showPopup” method name.

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".PopupMenuDemoActivity" >

    <Button
        android:id="@+id/buttonShowMePopup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:onClick="showPopup"
        android:text="Show Me Popup" />

</RelativeLayout>

It is always good idea to use resources to maintain strings.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">PopupMenuDemo</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="archive">Archive</string>
    <string name="delete">Delete</string>
    <string name="popup_menu_archive_selected">Archive is selected.</string>
    <string name="popup_menu_delete_selected">Delete is selected.</string>
</resources>

A new menu XML file must be added. Add a new Android XML with “Menu” Resource Type. Use “actions.xml” as its name. Please insert two items for this demo.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/archive" android:title="@string/archive"></item>
    <item android:id="@+id/delete" android:title="@string/delete"></item>
</menu>

Then we are pretty much ready to write code. For the sake of simplicity I decided to use the main activity (named PopupMenuDemoActivity) as a target of the “PopupMenu.OnMenuItemClickListener” interface. This means the activity should implement the interface. When the user selects an item, Android system will call the onMenuItemClick() callback.

package edu.kettering.popupmenudemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.Toast;

public class PopupMenuDemoActivity extends Activity 
		implements PopupMenu.OnMenuItemClickListener {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_popup_menu_demo);
	}

	public void showPopup(View v)
	{
		PopupMenu popupMenu = new PopupMenu(this, v);
		popupMenu.getMenuInflater().inflate(R.menu.actions, popupMenu.getMenu());
		popupMenu.setOnMenuItemClickListener(this);
		popupMenu.show();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.popup_menu_demo, menu);
		return true;
	}

	@Override
	public boolean onMenuItemClick(MenuItem item) {
		String msg;
		switch(item.getItemId()) {
		case R.id.archive:
			msg = getResources().getString(R.string.popup_menu_archive_selected);
			Toast.makeText(getApplicationContext(), 
                   msg, Toast.LENGTH_LONG).show(); 
			return true;
		case R.id.delete:
			msg = getResources().getString(R.string.popup_menu_delete_selected);
			Toast.makeText(getApplicationContext(), 
                    msg, Toast.LENGTH_LONG).show(); 
			return true;
		}
		return false;
	}

}

 

ProgressBar Demo

According to Android API Guides, we should avoid ProgressDialog. Instead, using ProgressBar in the layout is recommended.

Her is my layout xml. You may use other than RelativeLayout if you do not like it.

<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:paddingBottom="@dimen/activity_vertical_margin"
	android:paddingLeft="@dimen/activity_horizontal_margin"
	android:paddingRight="@dimen/activity_horizontal_margin"
	android:paddingTop="@dimen/activity_vertical_margin"
	tools:context=".ProgressBarDemo2Activity" >

<ProgressBar
	android:id="@+id/progressBar"
	style="?android:attr/progressBarStyleHorizontal"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_alignParentLeft="true"
	android:layout_alignParentRight="true"
	android:layout_alignParentTop="true" />
</RelativeLayout>

After putting a ProgressBar into my layout, I create a Runnable object and a Thread. Call the thread with the runnable object that has my own overridden run() method.

package edu.kettering.progressbardemo2;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ProgressBar;

public class ProgressBarDemo2Activity extends Activity {
	private ProgressBar mProgressBar;
	private int mProgress = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_progress_bar_demo2);

		mProgressBar = (ProgressBar)findViewById(R.id.progressBar);

		Runnable runWork = new Runnable() {
			@Override
			public void run() {
				while(mProgress < 100) {
					mProgress = doWork();
					mProgressBar.setProgress(mProgress);
				}
			}
		};
		Thread thread = new Thread(runWork);
		thread.start();
	}

	private int doWork() {
		// sleep 50 millisecond
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mProgress++;

		return mProgress;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.progress_bar_demo2, menu);
		return true;
	}
}

ProgressDialog Demo

This demo shows how to use ProgressDialog in the horizontal style. You can add your own task while the progress bar is displaying. This will also show how to update the progress bar as you are doing your task. For the sake of simplicity of source code I do not create onClickListener. Instead I use the “andoroid.onClick” property of a button.

In the layout xml, add a button and change onClick property with “startProgress” that we will be implementing in a moment.

<Button
    android:id="@+id/btnStartProgress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="startProgress"
    android:text="@string/start_progress" />

Here is the full source code.

package edu.kettering.progressbardemo;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;

public class ProgressBarDemo extends Activity {
	final static int maxValue = 500;
	private ProgressDialog progressBar;
	private int progress;
	private int progressSomthing;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_progress_bar_demo);
	}

	public void startProgress(View v) {
		progressBar = new ProgressDialog(v.getContext());
		progressBar.setCancelable(true);
		progressBar.setMessage("Wait...");
		progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		progressBar.setProgress(0);
		progressBar.setMax(maxValue);
		progressBar.show();

		progress = 0;
		progressSomthing = 0;

		// make a runnable to be used in the thread
		Runnable runProgress = new Runnable() {
			public void run() {
				while (progress < maxValue) {

					progress = doSomething();

					progressBar.setProgress(progress);
				}

				if (progress >= maxValue) {
					progressBar.dismiss();
				}
			}
		};

		Thread thread = new Thread(runProgress);
		thread.start();
	}

	// this should return a progress value
	public int doSomething() {
		// sleep 50 millisecond
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		progressSomthing++;

		return progressSomthing;
 	}
 }

DatePickerDialog Demo

This demo shows you how to use DatePickerDialog. You will see a warning “showDialog is deprecated” when you use “showDialog” method. First of all you could use, as of today, “showDialog” even though the message warns you. This link (http://www.technotalkative.com/android-datepickerdialog-example/) is an example that you can still use. However we do not know when it will stop working anyway since the method had been deprecated anyway.

Previously we used to use

  • showDialog(int id);
  • onCreateDialog(int id);

“showDialog” will be called in a handler of a button or something. And we need to prepare the onCreateDialog callback something like below.

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DATE_DIALOG_ID:
        return new DatePickerDialog(this, mDateSetListener, mYear, mMonth, mDay);
    }
    return null;
}

Android’s API Guides say “you should use a DialogFragment as a container for your dialog.” I do not want to create a DialogFragment to use DatePickerDialog. Many recently tutorials explain how to use DialogFragment to use even simple dialogs. Here is a good news. We could use DatePickerDialog without knowing DialogFragment.

The idea of the new approach is that we create an instance of the “DatePickerDialog” class and set properties before we show the dialog by the “show” method. I think that this is a more integrated way to manage dialogs.

mDatePickerDialog = new DatePickerDialog(v.getContext(), mDateSetListener,
                                         mYear, mMonth, mDay);
mDatePickerDialog.setCancelable(true);
mDatePickerDialog.setTitle("Pick a date");
mDatePickerDialog.show();
//showDialog(DATE_DIALOG_ID);

Full source code is as below.

package edu.kettering.datepickerdemoactivity;

import java.util.Calendar;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;

public class DatePickerDemoActivity extends Activity {
  private TextView mDateDisplay;
  private Button mPickDate;
  private int mYear;
  private int mMonth;
  private int mDay;
  private DatePickerDialog mDatePickerDialog;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_date_picker_demo);

    // get the current date
    final Calendar c = Calendar.getInstance();
    mYear = c.get(Calendar.YEAR);
    mMonth = c.get(Calendar.MONTH);
    mDay = c.get(Calendar.DAY_OF_MONTH);

    // get references of views
    mDateDisplay = (TextView) findViewById(R.id.dateDisplay);
    mPickDate = (Button) findViewById(R.id.pickDate);

    // add a click listener to the button
    mPickDate.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        mDatePickerDialog = new DatePickerDialog(v.getContext(),
                         mDateSetListener, mYear, mMonth, mDay);
        mDatePickerDialog.setCancelable(true);
        mDatePickerDialog.setTitle("Pick a date");
        mDatePickerDialog.show();
        //showDialog(DATE_DIALOG_ID);
      }
    });
    // display the current date in the TextView
    updateDisplay();
  }

  // update the date in the TextView
  private void updateDisplay() {
    mDateDisplay.setText(new StringBuilder()
             .append(mMonth + 1).append("-")
             .append(mDay).append("-")
             .append(mYear).append(" "));
  }

  // define a variable mDataSetListener
  private DatePickerDialog.OnDateSetListener mDateSetListener =
    new DatePickerDialog.OnDateSetListener() {
      public void onDateSet(DatePicker view, int year,
                            int monthOfYear, int dayOfMonth) {
        mYear = year;
        mMonth = monthOfYear;
        mDay = dayOfMonth;
        updateDisplay();
     }
   };
}
Follow

Get every new post delivered to your Inbox.

Join 147 other followers