Understanding User Interface in Android - Part 4: More Views(译)
无意中看到的几篇文章,想翻译出来分享给大家。不过声明,翻译后的意思不一定能完全表达作者的意图,如果想看原文,请参考:
http://mobiforge.com/designing/story/understanding-user-interface-android-part-4-more-views
在Android Views系列文章的最后一篇里,我们将继续介绍其他种类的View——Menu和一些额外cool的View。讨论的View包含:
- Context Menu
- Options Menu
- AnalogClock
- DigitalClock
- WebView
注意: 这篇文章中的所有例子,将延续前篇文章中创建的工程。
Menus
Menus对于不能在应用程序主UI上直接显示额外选项来说非常有用。在Android中,主要有两种Menu:
- Context Menu – 显示一个Activity中特定View的信息。在Android中,通过按下并Hold一段时间来激活上下文菜单。
- Options Menu – 显示当前Activity的信息。在Android中,通过按下MENU键来激活选项菜单。
图1显示了在浏览器应用程序中的选项菜单。无论用户何时按下MENU按钮,选项菜单都会显示。显示的菜单项取决于当前运行的Activity。
图1 浏览器程序中的选项菜单
图2展示了当用户按下并Hold当前页中显示的超链接时,会显示出上下文菜单。显示的菜单项取决于组件或当前选择的View。为了激活上下文菜单,用户可以通过选择屏幕上的项目、按下并Hold一段时间,或者通过简单的按下方向键盘中的中键方式。
图2 浏览器程序中的上下文菜单
为了在Android中实现Menu,通过在res/layout文件夹下添加一个新的文件并取名menu.xml。用以下元素进行填充:
<?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"
>
<Button android:id="@+id/btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text = "Hello, world!"
/>
</LinearLayout>
然后,添加一个新的类到src/net.learn2develop.AndroidViews文件夹中,并取名MenuExample.java。现在先不管这个文件。修改AndroidManifest.xml文件,注册新的Activity:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.learn2develop.AndroidViews"
android:versionCode="1"
android:versionName="1.0.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ViewsActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MenuExample"
android:label="@string/app_name" />
</application>
</manifest>
创建辅助方法
对于本节中的例子来说,你将在MenuExample.java文件中创建两个辅助方法,它们是CreateMenu()和MenuChoice()。定义这两个辅助方法和onCreate()方法,如下所示:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.Toast;
public class MenuExample extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
Button btn = (Button) findViewById(R.id.btn1);
btn.setOnCreateContextMenuListener(this);
}
private void CreateMenu(Menu menu)
{
menu.setQwertyMode(true);
MenuItem mnu1 = menu.add(0, 0, 0, "Item 1");
{
mnu1.setAlphabeticShortcut('a');
mnu1.setIcon(R.drawable.alert_dialog_icon);
}
MenuItem mnu2 = menu.add(0, 1, 1, "Item 2");
{
mnu2.setAlphabeticShortcut('b');
mnu2.setIcon(R.drawable.ic_popup_reminder);
}
MenuItem mnu3 = menu.add(0, 2, 2, "Item 3");
{
mnu3.setAlphabeticShortcut('c');
mnu3.setIcon(R.drawable.icon);
}
MenuItem mnu4 = menu.add(0, 3, 3, "Item 4");
{
mnu4.setAlphabeticShortcut('d');
}
menu.add(0, 3, 3, "Item 5");
menu.add(0, 3, 3, "Item 6");
menu.add(0, 3, 3, "Item 7");
}
private boolean MenuChoice(MenuItem item)
{
switch (item.getItemId()) {
case 0:
Toast.makeText(this, "You clicked on Item 1",
Toast.LENGTH_LONG).show();
return true;
case 1:
Toast.makeText(this, "You clicked on Item 2",
Toast.LENGTH_LONG).show();
return true;
case 2:
Toast.makeText(this, "You clicked on Item 3",
Toast.LENGTH_LONG).show();
return true;
case 3:
Toast.makeText(this, "You clicked on Item 4",
Toast.LENGTH_LONG).show();
return true;
case 4:
Toast.makeText(this, "You clicked on Item 5",
Toast.LENGTH_LONG).show();
return true;
case 5:
Toast.makeText(this, "You clicked on Item 6",
Toast.LENGTH_LONG).show();
return true;
case 6:
Toast.makeText(this, "You clicked on Item 7",
Toast.LENGTH_LONG).show();
return true;
}
return false;
}
}
CreateMenu()方法创建一堆菜单项,并修改了每个菜单项的外观。add方法中的参数包括:groupid, itemid, order和title。setAlphabeticShortcut()方法为菜单项设置了快捷键,这样,当用户按下特定的键时,菜单项就被选择。setIcon()方法为菜单项设置了图标。
MenuChoice()方法使用Toast类来显示选择的菜单项。接下来,拷贝两个图片(如图3所示)到res/drawable文件夹中。
Options Menu
为了在Activity中显示选项菜单,你需要重写两个方法——onCreateOptionsMenu()和onOptionsItemSelected()。onCreateOptionsMenu()方法在MENU按钮被按下时调用。在这个事件中,你需要调用CreateMenu()辅助方法来显示选项菜单。当一个菜单项被选中时,onOptionsItemSelected()方法会被调用。在这个情况下,调用MenuChoice()方法来显示选中的菜单项(和你想要做的任何事情):
public class MenuExample extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
}
private void CreateMenu(Menu menu)
{
//...
}
private boolean MenuChoice(MenuItem item)
{
//...
}
//---only created once---
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return MenuChoice(item);
}
}
修改ViewsActivity.java文件来启动MenuExample Activity:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
public class ViewsActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startActivity(new Intent(this, MenuExample.class));
}
}
按下F11来调试应用程序。当你按下MENU键时,你将看到如图4的选项菜单。
图4 显示选项菜单
注意菜单项1、2、3上显示的图标。此外,如果选项菜单包含6个以上菜单项时,这里将出现一个More菜单项来表示其它的菜单项。图4的右图显示了当按下More菜单项时以列表的形式显示的其它菜单项。
Context Menu
如果你想给Activity中的View关联一个上下文菜单的话,你需要调用特定View的setOnCreateContextMenuListener() 方法。举个例子,接下来的代码将展示如何给Button关联一个上下文菜单:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.Toast;
public class MenuExample extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
Button btn = (Button) findViewById(R.id.btn1);
btn.setOnCreateContextMenuListener(this);
}
private void CreateMenu(Menu menu)
{
//...
}
private boolean MenuChoice(MenuItem item)
{
//...
}
//---only created once---
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return MenuChoice(item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, view, menuInfo);
CreateMenu(menu);
}
@Override
public boolean onContextItemSelected(MenuItem item)
{
return MenuChoice(item);
}
}
和选项菜单一样,你需要重写onCreateContextMenu()和onContextItemSelected()方法。按下F11来调试应用程序。按下Button并Hold几秒钟,你将看到上下文菜单(如图5所示)。注意菜单项1-4的菜单名下方的快捷键。
图5 显示上下文菜单
其它Views
除了你已经看到的标准Views,Android SDK还提供了一些有意思的View,使得你的应用程序更加有趣味。在接下来的章节,你将了解以下Views:
- AnalogClock
- DigitalClock
- WebView
AnalogClock和DigitalClock
AnalogClock显示一个模拟的时钟。在main.xml文件中填入以下元素:
<?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"
>
<AnalogClock android:id="@+id/clock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
在ViewsActivity.java文件中,确保main.xml文件加载为Activity的UI:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
public class ViewsActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
按下F11,你将看到如图6所示的模拟时钟。
图6 动作中的模拟时钟
使用DigitalClock来取代模拟时钟,这样能看到一个数字时钟。
在main.xml文件中添加DigitalClock元素,如下所示:
<?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"
>
<AnalogClock android:id="@+id/clock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<DigitalClock android:id="@+id/clock2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
按下F11,图7同时显示了模拟时钟和数字时钟。
图7 动作中的数字时钟
WebView
WebView允许你在Android应用程序中嵌入一个网页浏览器。添加一个新的文件到res/layout文件夹中,取名webview.xml。并用以下元素进行填充:
<?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"
>
<WebView android:id="@+id/webview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text = "Hello, world!"
/>
</LinearLayout>
在src/net.learn2develop.AndroidViews文件夹下添加一个新的类,取名WebExample.java。并用以下内容填充:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class WebViewExample extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
WebView wv = (WebView) findViewById(R.id.webview1);
wv.loadUrl("http://www.mobiforge.com");
}
}
WebView的loadUrl()方法用于加载一个给定URL的页面。修改AndroidManifest.xml文件来注册新的Activity,并添加INTERNET权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.learn2develop.AndroidViews"
android:versionCode="1"
android:versionName="1.0.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ViewsActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WebViewExample"
android:label="@string/app_name" />
</application>
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
<uses-sdk android:minSdkVersion="3" />
</manifest>
为了让WebView工作,你需要在AndroidManifest.xml文件中添加INTERNET权限。修改ViewsActivity.java文件,来启动WebViewExample Activity:
package net.learn2develop.AndroidViews;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
public class ViewsActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startActivity(new Intent(this, WebViewExample.class));
}
}
按下F11来启动Android模拟器。图8显示了动作中的WebView。
图8 WebView正在显示一个网页
你还可以动态创建一个HTML字符串并在WebView中加载,使用loadDataWithBaseURL()方法:
WebView wv = (WebView) findViewById(R.id.webview1);
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = "<H1>A simple HTML page</H1><body>" +
"<p>The quick brown fox jumps over the lazy dog</p>";
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");
图9显示了加载HTML字符串的WebView。
图9 显示HTML字符串的内容
如果你有静态页面,你想通过工程直接加载,你可以把HTML页面放在package的assets文件夹中。图10显示了我在assets文件夹中添加了一个名为Index.html文件。
图10 在assets文件夹下添加HTML文件
Index.html的内容如下:
<h1>A simple HTML page</h1>
<body>
<p>The quick brown fox jumps over the lazy dog</p>
<img src='http://www.google.com/logos/Logo_60wht.gif'/>
</body>
为了将Index.html文件中储存的内容加载到WebView中,使用loadUrl()方法如下:
WebView wv = (WebView) findViewById(R.id.webview1);
wv.loadUrl("file:///android_asset/Index.html");
图11中,WebView加载了内容。
图11 使用WebView加载HTML页面
小结
在这篇文章中,你已经看到在Android应用程序中如何实现上下文菜单和选项菜单。另外,你还看到如何使用一些比较cool的View,如AnalogClock和DigitalClock。至此,Android Views系列文章告一段落。我希望你现在已经了解了Android中View如何工作,并拥有愉快的体验。