KPOP 최신가요 API를 공개합니다 |
xml 형태로 제공되며 앨범 이미지 링크도 제공합니다.
XML Paser 를 이용하시면 Android 용 앱이나 Widget 그리고 RSS Data로 가공이 가능하고 그 외 용도로 가공이 가능합니다.
차트는 실시간 순위입니다. (참고하시기 바랍니다)
Screenshot |
설명 |
API 주소 |
KPOP 최신가요 API를 공개합니다 |
xml 형태로 제공되며 앨범 이미지 링크도 제공합니다.
XML Paser 를 이용하시면 Android 용 앱이나 Widget 그리고 RSS Data로 가공이 가능하고 그 외 용도로 가공이 가능합니다.
차트는 실시간 순위입니다. (참고하시기 바랍니다)
Screenshot |
설명 |
API 주소 |
Note: I apologize to all diligent readers of this blog but I need to give a small reminder to those who have not read the two first articles of the ‘ListView Tips & Tricks’ series. I strongly suggest to all of them to look at the previous tips and tricks I have illustrated. Reading those posts is not mandatory but highly recommended as they may be mentioned here. Do not hesitate to learn more about emptiness handling and sectioning
Note: I do not know how many articles will be written in this series of tips and tricks about the ListView
widget. In the second opus, I gathered all sample codes into a single
repository on GitHub. This project will be augmented with each code I
will be developing in this series. For instance, all of the code you
will find in this page is already available in the ListViewTipsAndTricks
project. You can clone/fork it at the following GitHub page:
http://github.com/cyrilmottier/ListViewTipsAndTricks
In the previous article, we have learned how to section data inside a
ListView. I have also given you a few tips that might have helped you
to improve performance in your application. Providing a very smooth and
responsive UI is essential to users as mobile applications are a way for
them to improve their productivity. Performance and responsiveness are
great but I’m sure all of you know users are very demanding. They also
want their applications to be user-friendly, easy-to-use and …
beautiful. In this article we will focus on creating fancy and eye-candy
ListView
s
Along this post we will display a list of cheeses. I know this is far
from being a great set of data (especially for a guy that never eat
cheese like me ^^). The reason for this is I preferred focusing on the
actual code of the ListView
rather the data-fetching code.
I’m sure, you can all imagine cheeses as relevant and have enough
imagination to consider cheeses like something more ‘accurate’: tweets,
Google+ messages, etc.
Our goal in this post is to learn few tips to create well-designed ListView
-based applications. ListView
s
are widely used on the Android platform and must be designed keeping in
mind its actual purpose. For instance, the Contact app is regularly
used but the time taken by a user to find a contact must be as quick as
possible. To fulfill these requirements, the Android team developed a
very easy-to-read ListView
: clean, containing as few texts
as possible, large texts, plain background color, white texts on black
background, etc. Even if this is great for the ‘Contact’ app, this is
not a perfect and generic solution. Conversely, the ‘Messages’ app
contains a ListView
designed to be used as often but in a
slower way, rarely flinged, differentiating each participant of a
conversation, etc. The solution to this problem has been to create a ListView
with various background colors, a small but readable font, using grey
color for less important information, etc. In other word, a smooth ListView
is not enough: you have to design it constantly thinking about the way your customers will use it.
Let’s start by creating a ListActivity
displaying our list of cheeses. The first step is to create a layout containing our ListView
.
The code below shows you the layout we will be using afterwards in this
article. You can also find a graphic representation of this layout in
the screenshot below.
<?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="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> <LinearLayout style="@android:style/ButtonBar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:layout_gravity="center_vertical" android:text="@string/draw_selector_on_top" android:onClick="onDrawSelectorOnTop" /> <Button android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:layout_gravity="center_vertical" android:text="@string/use_selector_as_background" android:onClick="onUseSelectorAsBackground" /> </LinearLayout> </LinearLayout> |
As you may have noticed, the layout contains a ‘bottom bar’ with two
Buttons. We could have created a very basic layout … or even not
creating one at all and letting the ListActivity
create a full-sized ListView
but we will actually use those Button
s in the rest of this post to switch between different ’styling’ methods.
The code of our basic ListActivity
is given below:
package com.cyrilmottier.android.listviewtipsandtricks; import android.app.ListActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.cyrilmottier.android.listviewtipsandtricks.data.Cheeses; public class FancyListActivity extends ListActivity { private FancyAdapter mFancyAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fancy_list); mFancyAdapter = new FancyAdapter(Cheeses.CHEESES); setListAdapter(mFancyAdapter); } private class FancyAdapter extends BaseAdapter { private String[] mData; public FancyAdapter(String[] data) { mData = data; } @Override public int getCount() { return mData.length; } @Override public String getItem(int position) { return mData[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView result; if (convertView == null) { result = (TextView) getLayoutInflater().inflate(R.layout.text_item, parent, false); } else { result = (TextView) convertView; } final String cheese = getItem(position); result.setText(cheese); return result; } } } |
If we look at the overall appearance of this UI, we have a very basic
ListView with a black background. When the user taps an item, the
background of this itemview turns orange while the text turns black.
Where do those colors come from? In the source code of our application,
there is no reference to colors nor Drawable
s. The actual reason is all styles come from the Application
/Activity
theme. As we have set no theme to our application, the default theme (@android:style/Theme
) is used.
Let’s start customizing our ListView
! The first thing we
can change from the default theme is the color of the pressed itemview.
In order to do that, we will use the android:listSelector
XML attribute which is equivalent to the ListView.setSelector(int)
method. The list selector is a Drawable
drawn by the ListView
as the background of the pressed/focused itemview. The ListView
manages all types of Drawable
s but the preferred Drawable
is usually the StateListDrawable
. This Drawable
changes its appearance based on its current state (focused, pressed,
selected, etc.). The capture below shows the list selector we want to
develop in the focused and pressed states:
Note: As some of you may know, I am a huge fan of Android Drawable
s.
I think they are one of the most amazing features of the Android UI
toolkit. They are so powerful I have given a talk named “Mastering
Drawables” during the Droidcon (London - 2010) as well as the Android
Developer Labs (Paris - 2010). If you want to know more about Drawable
s, you can have a look at the slides (in French only … it seems I have lost the English version of those slides) on Slideshare and the sample codes I made on GitHub
Edit (2011-09-24): I finally succeed to find the English version of the slides. You can download them here
In this example, we will create a brand new list selector that
displays a nice gradient beneath the pressed/focused itemview. The first
thing we need to do is to create two GradientDrawable
s: the first one for the pressed state and the second one for the focused state. The GradientDrawable
s below are respectively called list_selector_pressed.xml and list_selector_focused.xml and can be found in the res/drawable
folder:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#fb9d23" android:endColor="#ffc579" android:angle="90" /> </shape> |
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#f5c98c" android:endColor="#f7ddb8" android:angle="90" /> </shape> |
We can now create our own list selector that references the two previous Drawable
s (this is where the magic happens ^^). This file is located in the res/drawable
folder and its name is list_selector.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" /> <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" /> <item android:drawable="@android:color/transparent" /> </selector> |
The only thing we need to do now is to apply this brand new list selector to our ListView
. You can do it by adding android:listSelector="@drawable/list_selector"
to the ListView
tag in your layout.
Note: Using a color as part of your list selector may entirely fill your ListView
. This problem comes from the fact a ColorDrawable
does not respect its bounds: it entirely fills the clip rect of the Canvas
in which it is drawn into. I have always considered this as a bug but
nothing has been fixed until … Android 3.0 (Honeycomb)! As a result,
using a ColorDrawable
in your list selector is strongly
discouraged. Fortunately, this article is entitled ‘ListView tips &
tricks’ and here is an easily way to get round this bug: instead of
setting a ColorDrawable
, use a Drawable
that respect its bounds such as a GradientDrawable
or a NinePatchDrawable
. The code below shows a GradientDrawable
that can be used in replacement of a regular ColorDrawable
.
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#fb9d23" /> </shape> |
ListView
s provides a lot of “styling” features. In this paragraph we will focus on various methods that may be used to style your ListView
. Please note those most of those tips are given “as it” and are not part of the sample code.
By default, an Android View
has a transparent
background. Although it seems natural … transparency involves a lot of
calculation when rendering your application on screen. In order to avoid
blending and make the rendering faster while scrolling/flinging, the ListView
widget uses a ’scrolling cache’ mechanism. This mechanism consists on taking an opaque screenshot of all visible child View
s (in other words, it draws the content of each itemview in a Bitmap
)
and directly draws those screenshots when necessary. The color used to
make those screenshots opaque is the one given by the cache color hint.
If your ListView
turns opaque (black for instance) when scrolling that because you need to set the cache color hint to the actual color of your ListView
background. Setting this property @android:color/transparent
will fix the problem but will also disable the optimization …
If you want to know more about the cache color hint optimization I strongly recommend you to have a look at a really great article written by Romain Guy. You can read it on the Android Developer Blog
Contrary to the ScrollView
widget, ListView
has a built-in support for dividers. By default, a divider is a 1-pixel
tall line that is used to separate two itemviews. You can style/modify
this property with the android:divider
XML attribute. Setting a new divider can be done with a color or a Drawable
. When drawing the content, the ListView
will automatically look at the height of the divider to part the
itemviews. In other words, it means you can use a very complex Drawable
as divider and your ListView
will automatically measure it and draw it when necessary.
This looks amazingly powerful and easy, isn’t it? It actually is … but there is little a problem. Some Drawable
s (for instance the ColorDrawable
) has no intrinsic height (which means a call to Drawable.getIntrinsicHeight()
returns -1). In order to by-pass this problem, ListView
provides a android:dividerHeight
XML attribute that asks for a dimension.
Note: The previously detailed problem concerning the un-respected bounds does not apply to dividers. This is odd, isn’t it? Indeed, ListView
has an internal mechanism clipping the Drawable
to the correct rectangle on screen when the divider is a ColorDrawable
. As a result you can safely use colors when styling your dividers.
By default, a ListView
fades away at the top and bottom edges once the content is larger than the actual size of the ListView
. This property is called fading edge and can be easily removed or modified using android:fadingEdge
and/or android:fadingEdgeLength
. You can look at the sample code of this post in which I have prefered removing this Android feature by adding a android:fadingEdge="none"
in the XML attributes of our ListView
.
Sooner, we have discovered a way to create a custom list selector. If
you look closely to the image, you will notice the text has a different
color between the normal and pressed states. Changing the text color
may be mandatory in some cases where the background color of a pressed
itemview is very close to the color of the text. In order to change the
color of the text depending on the current state of the itemview, you
can use a ColorStateList
. I will not describe how to use it here but you can take a look at the framework documentation. This class and its use is described very clearly in the Android developer guide
Since Android 2.3, ListView
s gives a visual feedback when the user tries to scroll the content of the ListView
over its bounds. This feedback looks like a ‘halo’ at the bottom/top of the ListView
. You can set your own Drawable
using one of the setOverscroll[Footer/Header](Drawable)
method.
Changing the background color of a ListView
can be rather complex. The next part gives you a few tips and tricks you can use to create eye-candy and unique ListView
s.
Our goal is to change the background of our UI to a light color. We
will also try to emphasize some cheeses by setting the background of
their itemview to a more noticeable color. The screenshots below shows
our final ListView
depending on the method used:
The simplest approach of changing the UI background color is to change the background color of the ListView
. In order to do that, we simply have to use the android:background
XML attribute or one of the setBackground[Color|Resource|Drawable]
method.
The main problem with this approach is the background is applied
globally. In other words, it means you don’t a control over each
itemview as the background applied to the entire ListView
. This works particularly great with a plain color but this method will not allow you style two itemviews differently.
In the previous method, we have chosen to change the background of the entire ListView
.
If we want to have a control over each itemview appearance it makes
sense to change the background of each of our itemviews independently.
The code below shows you how to apply a background depending on whether
the underlying data is special or not:
@Override public View getView(int position, View convertView, ViewGroup parent) { TextView result; if (convertView == null) { result = (TextView) getLayoutInflater().inflate(R.layout.text_item, parent, false); result.setTextColor(Color.BLACK); } else { result = (TextView) convertView; } final String cheese = getItem(position); result.setText(cheese); result.setBackgroundResource(isSpecial(cheese) ? R.drawable.list_item_background_special : R.drawable.list_item_background_normal); return result; } |
If you compile and run this example, everything will work perfectly fine … until you try to press an itemview. Indeed, using the previous technique, the customized list selector we created never shows up. It may look like a bug at first but this is actually completely normal. Let’s look at how things are drawn the following diagram (you can click on the image to access to a larger version):
As you can see, Android first draws the ListView
background as well as the dividers. Then, the system draws the list selector. Finally, ListView
renders all itemviews on top of that. Thanks to this diagram, it is
clear the list selector will never be visible with opaque background set
to itemviews. Fortunately, I have a listed a few solutions you can
implement.
The ListView
or more globally the AbsListView
offers a android:drawSelectorOnTop
XML attribute and its Java equivalent setDrawSelectorOnTop(boolean)
. As mentioned in the method’s name, setting this property to true will indicate the ListView
to draw the selector on top of each itemview. Even if this looks like a
good option, drawing selector on top does not allow you to have opaque
list selector as the content of your itemview will be completely hidden.
I have seen a lot of samples over the Internet using the OnItemClickListener
and OnItemSelectedListener
in order to be notified the background must be changed to transparent …
This can work but I think this is a pure hack considering the features
available in the Android framework. Even if this technique is probably
great on some mobile platforms could you please guys stop using it on
the Android platform. This is not a correct nor easy way to do it on
Android. As a result, you can probably guess why there is no line of
code in this article explaining the trick hack.
As we have seen previously, our biggest problem comes the fact the
background is opaque and hides the list selector when the itemview is
pressed. Hence, we need to find a way to make the background transparent
when pressed. This looks like something we have already done and some
of you may have understood where I want to get to … Hurray, you are
right! The trick consists on using a StateListDrawable
as the background of each itemview. This Drawable
will have the exact opposite behavior of the list selector: it will be
opaque by default and will become transparent when pressed, focused or
selected. The code below refers to the list_selector_normal.xml (the list_selector_special.xml is very similar and is not available here. Look at the sample code for more details):
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@android:color/transparent" /> <item android:state_selected="true" android:drawable="@android:color/transparent" /> <item android:state_focused="true" android:drawable="@android:color/transparent" /> <item android:drawable="@drawable/list_item_background_normal" /> </selector> |
This trick can even be pushed to its paroxysm by setting the list selector of your ListView to null
or a transparent color and letting each itemview handle the all states
itself. You only thing you need to do here is to create a final StateListDrawable
containing the background (normal state) as well as the gradient used
as visual interaction feedback (pressed/focused state). This method
works pretty well and does not suffer from the previously mentioned
problem regarding ColorDrawable (the color is drawn at the itemview
level not at the ListView
level) but it does not force you
to have consistent pressed/focused states between your itemviews. Even
if it is usually okay to have different Drawable
for the ‘normal’ background it is generally not recommended to have different Drawable
between itemviews.
Although we have just scratched the surface of the styling possibilities, you now have a large set of keys to design eye-candy ListView
s. Do not hesitate to use those tips always keeping in mind what the important questions are: “What’s the real purpose on this ListView
?”, “What are my users’ expectations?”, “Do I need to focus on productivity, readability, efficiency or something else?”, etc.
I hope you have appreciated this article. I know it is quite a long
post but let’s say this will be the only one I will be posting this
month of holidays ^^. Do not hesitate to leave a comment below if you
have questions, if you think I have made a mistake somewhere or simply
if you want to thank me for this! Have fun styling your ListView
s!
Android SystemInfo (0) | 2012.06.02 |
---|---|
Android 제조사별 소스 (0) | 2012.06.01 |
Android - Dialog (1) | 2012.04.23 |
Android 에서 화면 회전하는 방법 (0) | 2012.04.23 |
Android Emulator Market 2.2 (마켓버전 Image) (0) | 2012.04.22 |
A dialog is usually a small window that appears in front of the current Activity. The underlying Activity loses focus and the dialog accepts all user interaction. Dialogs are normally used for notifications that should interupt the user and to perform short tasks that directly relate to the application in progress (such as a progress bar or a login prompt).
The Dialog
class is the base class for creating dialogs. However, you
typically should not instantiate a Dialog
directly. Instead, you should use one
of the following subclasses:
AlertDialog
ProgressDialog
DatePickerDialog
TimePickerDialog
If you would like to customize your own dialog, you can extend the
base Dialog
object or any of the subclasses listed above and define a new layout.
See the section on Creating a Custom Dialog below.
Dialog Design
For design guidelines, read Android Design's Dialogs guide.
A dialog is always created and displayed as a part of an Activity
.
You should normally create dialogs from within your Activity's
onCreateDialog(int)
callback method.
When you use this callback, the Android system automatically manages the state of
each dialog and hooks them to the Activity, effectively making it the "owner" of each dialog.
As such, each dialog inherits certain properties from the Activity. For example, when a dialog
is open, the Menu key reveals the options menu defined for the Activity and the volume
keys modify the audio stream used by the Activity.
Note: If you decide to create a dialog outside of the
onCreateDialog()
method, it will not be attached to an Activity. You can, however,
attach it to an Activity with setOwnerActivity(Activity)
.
When you want to show a dialog, call
showDialog(int)
and pass it an integer that uniquely identifies the
dialog that you want to display.
When a dialog is requested for the first time, Android calls
onCreateDialog(int)
from your Activity, which is
where you should instantiate the Dialog
. This callback method
is passed the same ID that you passed to showDialog(int)
.
After you create the Dialog, return the object at the end of the method.
Before the dialog is displayed, Android also calls the optional callback method
onPrepareDialog(int, Dialog)
. Define this method if you want to change
any properties of the dialog each time it is opened. This method is called
every time a dialog is opened, whereas onCreateDialog(int)
is only
called the very first time a dialog is opened. If you don't define
onPrepareDialog()
, then the dialog will
remain the same as it was the previous time it was opened. This method is also passed the dialog's
ID, along with the Dialog object you created in onCreateDialog()
.
The best way to define the onCreateDialog(int)
and
onPrepareDialog(int, Dialog)
callback methods is with a
switch statement that checks the id parameter that's passed into the method.
Each case should check for a unique dialog ID and then create and define the respective Dialog.
For example, imagine a game that uses two different dialogs: one to indicate that the game
has paused and another to indicate that the game is over. First, define an integer ID for
each dialog:
static final int DIALOG_PAUSED_ID = 0;
static final int DIALOG_GAMEOVER_ID = 1;
Then, define the onCreateDialog(int)
callback with a
switch case for each ID:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_PAUSED_ID:
// do the work to define the pause Dialog
break;
case DIALOG_GAMEOVER_ID:
// do the work to define the game over Dialog
break;
default:
dialog = null;
}
return dialog;
}
Note: In this example, there's no code inside the case statements because the procedure for defining your Dialog is outside the scope of this section. See the section below about Creating an AlertDialog, offers code suitable for this example.
When it's time to show one of the dialogs, call showDialog(int)
with the ID of a dialog:
showDialog(DIALOG_PAUSED_ID);
When you're ready to close your dialog, you can dismiss it by calling
dismiss()
on the Dialog object.
If necessary, you can also call dismissDialog(int)
from the
Activity, which effectively calls dismiss()
on the
Dialog for you.
If you are using onCreateDialog(int)
to manage the state
of your dialogs (as discussed in the previous section), then every time your dialog is
dismissed, the state of the Dialog
object is retained by the Activity. If you decide that you will no longer need this object or
it's important that the state is cleared, then you should call
removeDialog(int)
. This will remove any internal references
to the object and if the dialog is showing, it will dismiss it.
If you'd like your application to perform some procedures the moment that a dialog is dismissed, then you should attach an on-dismiss listener to your Dialog.
First define the DialogInterface.OnDismissListener
interface.
This interface has just one method,
onDismiss(DialogInterface)
, which
will be called when the dialog is dismissed.
Then simply pass your OnDismissListener implementation to
setOnDismissListener()
.
However, note that dialogs can also be "cancelled." This is a special case that indicates
the dialog was explicitly cancelled by the user. This will occur if the user presses the
"back" button to close the dialog, or if the dialog explicitly calls cancel()
(perhaps from a "Cancel" button in the dialog). When a dialog is cancelled,
the OnDismissListener will still be notified, but if you'd like to be informed that the dialog
was explicitly cancelled (and not dismissed normally), then you should register
an DialogInterface.OnCancelListener
with
setOnCancelListener()
.
An AlertDialog
is an extension of the Dialog
class. It is capable of constructing most dialog user interfaces and is the suggested dialog type.
You should use it for dialogs that use any of the following features:
To create an AlertDialog, use the AlertDialog.Builder
subclass.
Get a Builder with AlertDialog.Builder(Context)
and
then use the class's public methods to define all of the
AlertDialog properties. After you're done with the Builder, retrieve the
AlertDialog object with create()
.
The following topics show how to define various properties of the AlertDialog using the
AlertDialog.Builder class. If you use any of the following sample code inside your
onCreateDialog()
callback method,
you can return the resulting Dialog object to display the dialog.
To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right,
use the set...Button()
methods:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
First, add a message for the dialog with
setMessage(CharSequence)
. Then, begin
method-chaining and set the dialog
to be not cancelable (so the user cannot close the dialog with the back button)
with setCancelable(boolean)
. For each button,
use one of the set...Button()
methods, such as
setPositiveButton()
, that accepts the name for the button and a
DialogInterface.OnClickListener
that defines the action to take
when the user selects the button.
Note: You can only add one of each button type to the AlertDialog. That is, you cannot have more than one "positive" button. This limits the number of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the actual functionality of your buttons, but should help you keep track of which one does what.
To create an AlertDialog with a list of selectable items like the one shown to the right,
use the setItems()
method:
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
First, add a title to the dialog with
setTitle(CharSequence)
.
Then, add a list of selectable items with
setItems()
, which accepts the array of items to display and a
DialogInterface.OnClickListener
that defines the action to take
when the user selects an item.
To create a list of multiple-choice items (checkboxes) or
single-choice items (radio buttons) inside the dialog, use the
setMultiChoiceItems()
and
setSingleChoiceItems()
methods, respectively.
If you create one of these selectable lists in the
onCreateDialog()
callback method,
Android manages the state of the list for you. As long as the Activity is active,
the dialog remembers the items that were previously selected, but when the user exits the
Activity, the selection is lost.
Note: To save the selection when the user leaves or pauses the Activity, you must properly save and restore the setting throughout the activity lifecycle. To permanently save the selections, even when the Activity process is completely shutdown, you need to save the settings with one of the Data Storage techniques.
To create an AlertDialog with a list of single-choice items like the one shown to the right,
use the same code from the previous example, but replace the setItems()
method with
setSingleChoiceItems()
:
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
The second parameter in the
setSingleChoiceItems()
method is an integer value for the checkedItem, which indicates the
zero-based list position of the default selected item. Use "-1" to indicate that no item should be
selected by default.
A ProgressDialog
is an extension of the AlertDialog
class that can display a progress animation in the form of a spinning wheel, for a task with
progress that's undefined, or a progress bar, for a task that has a defined progression.
The dialog can also provide buttons, such as one to cancel a download.
Opening a progress dialog can be as simple as calling
ProgressDialog.show()
. For example, the progress dialog shown to the right can be
easily achieved without managing the dialog through the
onCreateDialog(int)
callback,
as shown here:
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
"Loading. Please wait...", true);
The first parameter is the application Context
,
the second is a title for the dialog (left empty), the third is the message,
and the last parameter is whether the progress
is indeterminate (this is only relevant when creating a progress bar, which is
discussed in the next section).
The default style of a progress dialog is the spinning wheel. If you want to create a progress bar that shows the loading progress with granularity, some more code is required, as discussed in the next section.
To show the progression with an animated progress bar:
ProgressDialog(Context)
.setProgressStyle(int)
and
set any other properties, such as the message.show()
or return the ProgressDialog from the
onCreateDialog(int)
callback.setProgress(int)
with a value for
the total percentage completed so far or incrementProgressBy(int)
with an incremental value to add to the total percentage completed so far.For example, your setup might look like this:
ProgressDialog progressDialog;
progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
The setup is simple. Most of the code needed to create a progress dialog is actually
involved in the process that updates it. You might find that it's
necessary to create a second thread in your application for this work and then report the progress
back to the Activity's UI thread with a Handler
object.
If you're not familiar with using additional
threads with a Handler, see the example Activity below that uses a second thread to
increment a progress dialog managed by the Activity.
If you want a customized design for a dialog, you can create your own layout
for the dialog window with layout and widget elements.
After you've defined your layout, pass the root View object or
layout resource ID to setContentView(View)
.
For example, to create the dialog shown to the right:
custom_dialog.xml
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>
This XML defines an ImageView
and a TextView
inside a LinearLayout
.
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
After you instantiate the Dialog, set your custom layout as the dialog's content view with
setContentView(int)
, passing it the layout resource ID.
Now that the Dialog has a defined layout, you can capture View objects from the layout with
findViewById(int)
and modify their content.
A dialog made with the base Dialog class must have a title. If you don't call
setTitle()
, then the space used for the title
remains empty, but still visible. If you don't want
a title at all, then you should create your custom dialog using the
AlertDialog
class. However, because an AlertDialog is created easiest with
the AlertDialog.Builder
class, you do not have access to the
setContentView(int)
method used above. Instead, you must use
setView(View)
. This method accepts a View
object,
so you need to inflate the layout's root View object from
XML.
To inflate the XML layout, retrieve the LayoutInflater
with
getLayoutInflater()
(or getSystemService()
),
and then call
inflate(int, ViewGroup)
, where the first parameter
is the layout resource ID and the second is the ID of the root View. At this point, you can use
the inflated layout to find View objects in the layout and define the content for the
ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the
inflated layout for the dialog with setView(View)
.
Here's an example, creating a custom layout in an AlertDialog:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
Using an AlertDialog for your custom layout lets you take advantage of built-in AlertDialog features like managed buttons, selectable lists, a title, an icon and so on.
For more information, refer to the reference documentation for the
Dialog
and AlertDialog.Builder
classes.
Android 제조사별 소스 (0) | 2012.06.01 |
---|---|
ListView Tips & Tricks #3: Create fancy ListViews (1) | 2012.04.25 |
Android 에서 화면 회전하는 방법 (0) | 2012.04.23 |
Android Emulator Market 2.2 (마켓버전 Image) (0) | 2012.04.22 |
Android Emulator Skin (Simple Skin) (0) | 2012.04.18 |
Android 에서 화면 회전하는 방법 |
ListView Tips & Tricks #3: Create fancy ListViews (1) | 2012.04.25 |
---|---|
Android - Dialog (1) | 2012.04.23 |
Android Emulator Market 2.2 (마켓버전 Image) (0) | 2012.04.22 |
Android Emulator Skin (Simple Skin) (0) | 2012.04.18 |
Android Emulator 에 한국어 TTS 설치하기 (2/2) (0) | 2012.04.17 |
Android Emulator Market 2.2 (마켓버전 Image) |
Android Emulator 에서 Market 을 사용할 수 있도록 해주는 Image 파일 입니다.
Emualtor 에서 적용 시키시면 안드로이드 Maket을 사용하실 수 있습니다.
설치방법 |
Download |
Android - Dialog (1) | 2012.04.23 |
---|---|
Android 에서 화면 회전하는 방법 (0) | 2012.04.23 |
Android Emulator Skin (Simple Skin) (0) | 2012.04.18 |
Android Emulator 에 한국어 TTS 설치하기 (2/2) (0) | 2012.04.17 |
Android Emulator 에 한국어 TTS 설치하기 (1/2) (11) | 2012.04.17 |
Android Emulator Skin (Simple Skin) |
Android Emulator 용 Simple 한 Skin을 제작하였습니다.
기존에 Emulator Skin 은 공간도 많이 잡아 먹고 쓸데없이 크기만 해서 최대한 작게 만들도록 했습니다.
사용 방법 |
Download |
Android 에서 화면 회전하는 방법 (0) | 2012.04.23 |
---|---|
Android Emulator Market 2.2 (마켓버전 Image) (0) | 2012.04.22 |
Android Emulator 에 한국어 TTS 설치하기 (2/2) (0) | 2012.04.17 |
Android Emulator 에 한국어 TTS 설치하기 (1/2) (11) | 2012.04.17 |
Android Application Development Tutorial (0) | 2012.04.10 |
Tistory Cumulus Flash tag cloud by BLUEnLIVE requires Flash Player 9 or better.