Wednesday, August 10, 2011

Using a PopupWindow in Android


If a user selects Search from the menu, a PopupWindow is displayed for the user to enter some criteria and search Connexions. I am using a PopupWindow because the usual Android search box will not work with the Tabs displayed when the app opens. I will probably fix this soon by switching to an ActionBar for the tabs, but for now, I am using a PopupWindow. The PopupWindow allowed me to use the same logic for Search on every screen.

Using a PopupWindow requires a couple of things: a layout and the code to create, display and handle the response to the PopupWindow.

The Layout I used is pretty simple. It is in the search_popup.xml file.

android:id="@+id/popup_menu_root"
android:background="#006699"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize = "18sp"
android:text="Search"
android:textColor="#FFFFFF"
android:padding="3px"
/>
android:id="@+id/searchCriteria"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
android:id="@+id/search_button"
android:src="@drawable/magnify"
android:background="@drawable/button_background"
android:layout_width="40px"
android:layout_height="40px"
android:layout_marginLeft="3px"/>



There is a TextView for the label, an EditText for the search criteria and an ImageButton for the search icon. There are some bad coding practices I haven't cleaned up yet like putting the colors directly in the layout instead of in the colors.xml file.

The code for the PopupWindow is in the SearchHandler class.

public void displayPopup(final Context context)
{
popUp = new PopupWindow(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.search_popup, null, true);
popUp = new PopupWindow(layout, 300, 125, true);
popUp.setBackgroundDrawable(new BitmapDrawable());
popUp.setOutsideTouchable(true);
popUp.setAnimationStyle(R.style.Animations_GrowFromBottom);
popUp.setTouchInterceptor(new OnTouchListener() {

public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE)
{
popUp.dismiss();
return true;
}
return false;
}
});
final EditText searchCriteria = (EditText)layout.findViewById(R.id.searchCriteria);
ImageButton searchButton = (ImageButton)layout.findViewById(R.id.search_button);
searchButton.setOnClickListener(new OnClickListener()
{

public void onClick(View v)
{
String searchFor = searchCriteria.getText().toString();
performSearch(searchFor, Constants.CNX_SEARCH, context);
}
});
popUp.showAtLocation(layout, Gravity.TOP, 0, 30);
}


The displayPopup() method sets the properties on the popup. These are the layout, the outside touchable property and an animation. The layout is setup much like using a Menu. The outside touchable property allows the user to touch outside the popup. If the user does, the popup is dismissed. The animation runs when the popup is opened. It appears to come from the bottom of the screen. If the user selects the Search button, performSearch() is called.

private void performSearch(String searchFor, int searchType, Context context)
{
try
{
Content content = new Content();
content.setUrl(new URL(createQueryString(searchFor, searchType)));
content.setTitle(context.getString(R.string.search_title) + searchFor);
Intent webintent = new Intent(context, WebViewActivity.class);
ContentCache.setObject(context.getString(R.string.webcontent), content);
context.startActivity(webintent);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}



The performSearch() method creates the search query URL and passes it to the WebViewActivity which displays the results from Connexions.

You can browse the source or download a zip file of the source. Connexions for Android is available in the Android Market or from the Connexions website.