【发布时间】:2011-06-28 11:18:20
【问题描述】:
我正在为 Android 开发一个 RSS 新闻提要应用程序,并使用 Toast.makeText() 显示新闻或当前更新。它必须在点击该消息/新闻时进入网络。问题是Toast 没有 API/功能,我可以点击它并在网络上阅读全文。
主要要求是我需要一一显示新闻,这样我就不能使用列表或任何其他小部件。
谁能建议我应该使用什么 UI 元素来解决这个问题?
【问题讨论】:
我正在为 Android 开发一个 RSS 新闻提要应用程序,并使用 Toast.makeText() 显示新闻或当前更新。它必须在点击该消息/新闻时进入网络。问题是Toast 没有 API/功能,我可以点击它并在网络上阅读全文。
主要要求是我需要一一显示新闻,这样我就不能使用列表或任何其他小部件。
谁能建议我应该使用什么 UI 元素来解决这个问题?
【问题讨论】:
如果新闻量非常低,您可以按照建议使用通知,但我假设 RSS 提要可能有很多要通知的内容,如果您想一一显示它们,它会淹没通知列表。
虽然无法点击 Toast,但您可以创建具有特殊主题的 Activity 并模拟 Toast 行为。
好的,我们开始吧! =)
为了清楚起见,我最终编写了一个充当 Toast 的应用程序的完整示例。
首先我们需要一个类来充当我们的 Toast。这个类只会展示自己并在给定的时间后完成。您也可以处理其他事件以满足您的需求,但这是重现 Toast 行为所必需的最低限度。
package com.rchiossi.popup;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class MyPopup extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_popup);
String message = getIntent().getStringExtra("message");
TextView messageView = (TextView) findViewById(R.id.message);
messageView.setText(message);
Handler handler = new Handler();
long delay = 1000;
handler.postDelayed(new Runnable() {
@Override
public void run() {
MyPopup.this.finish();
}
}, delay);
}
}
如您所见,该类获取一个已作为 Extra 传递给启动 Activity 的 Intent 的 String,设置要显示的文本并设置一个 1000 毫秒的计时器以调用 finish() 方法。可以调整显示时间以更好地适应用户体验。
这个活动的布局非常简单:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@android:drawable/toast_frame"/>
</RelativeLayout>
这种布局只不过是一个空白屏幕,中间有一个文本。这里的技巧是将 TextView 背景设置为“@android:drawable/toast_frame”,这是 Toast 的默认背景。
现在,为了最后的润色,您需要在 AndroidManifest.xml 中设置主题,将应用背景设置为透明并移除标题。
<activity android:name=".MyPopup"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
</activity>
这里的诀窍是 android:theme 属性。 Theme.Translucent.NoTitleBar 将为我们提供一个具有透明背景且没有标题栏的 Activity。因此,当显示活动时,只有文本和 Toast 背景是可见的。
很好,现在您已经锁定并加载了一个可以工作的假吐司。但是怎么用呢?! 首先,我们创建一个虚拟应用程序作为我们的弹出启动器。您的项目中不需要这个,因为您自己的班级将启动 Toast。
package com.rchiossi.popup;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Main extends Activity {
/** Called when the activity is first created. */
private int mCount = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(Main.this,MyPopup.class);
intent.putExtra("message", "My popup number " + mCount);
mCount++;
startActivity(intent);
}
});
}
}
这个应用程序基本上只是一个按钮,当按下它时会显示一个带有消息的 Toast。如您所见,为了告诉您的 Toast 应用程序要显示什么消息,我们使用 Intent.putExtra(name,message) 方法。当 MyPopup 开始使用 Intent.getStringExtra(name) 方法时,此数据被抢救。
您可以从这里获取我的示例的源代码: http://www.mediafire.com/file/7vmuy8244vwh4dk/PopItUp.zip
希望对你有所帮助。 =)
【讨论】:
您可以使用可点击元素模拟类似 toast 的行为,但这需要一些工作。
最简单的方法是在 Activity 中使用 RelativeLayout。如果您还没有使用RelativeLayout,您可以简单地将您当前的布局包装成一个,然后将其设置为layout_alignParentTop=true,并将layout_width 和layout_height 设置为fill_parent。
在您的 RelativeLayout 内部(在所有其他内容下方,因此它不会被 Activity 中的其余元素隐藏),将您的可点击元素与 layout_alignParentBottom 添加为 true,并使用 layout_marginBottom 添加一些填充。这个元素可以是一个简单的 TextView,也可以是你想要的复杂的。在 xml 中将可见性设置为“已消失”,并且您的代码通常会显示 toast,您可以将可见性设置为“可见”。要摆脱它,您可以使用 Handler.postDelayed 将可见性设置回“消失”,或者如果您想要更漂亮,您可以使用 AlphaAnimation 淡入/淡出。
【讨论】:
自定义对话框怎么样?你可以让你的对话框看起来和或多或少像吐司一样。
【讨论】:
正如您所发现的,Toasts 绝对没有用户交互。鉴于他们的目的,这不太可能改变。
关于我能想到的唯一其他事情就是改用Notifications。
【讨论】: