Reputation: 32113
I have a need to show a minimally-intrusive non-blocking notification which is not tied to the activity it is shown in (like a Toast) and which is clickable. Does anyone have any idea whether or not this is possible? Unfortunately, it appears that Toast notifications (custom or otherwise) are not clickable (i.e. setting an OnClickListener on its views has no effect). All the alternatives that I'm aware of (i.e. AlertDialog, PopupWindow and Crouton) seem to show a notification which is tied to the activity it is shown in (i.e. they won't continue showing when the activity finishes). Any suggestions?
Upvotes: 4
Views: 8391
Reputation: 1493
You can use PopupWindow
, add an onClickListener
and add a handler
to auto cancel it after n times (just like the behavior of a toast
). Something like this:
public static void showToast(Activity a, String title, String message) {
// inflate your xml layout
LayoutInflater inflater = a.getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) a.findViewById(R.id.toast_layout_root));
// set the custom display
((TextView) layout.findViewById(R.id.title)).setText(title);
((TextView) layout.findViewById(R.id.message)).setText(message);
// initialize your popupWindow and use your custom layout as the view
final PopupWindow pw = new PopupWindow(layout,
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, true);
// set windowType to TYPE_TOAST (requires API 23 above)
// this will make popupWindow still appear even the activity was closed
pw.setWindowLayoutType(WindowManager.LayoutParams.TYPE_TOAST);
pw.showAtLocation(layout, Gravity.CENTER | Gravity.TOP, 0, 500);
// handle popupWindow click event
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// do anything when popupWindow was clicked
pw.dismiss(); // dismiss the window
}
});
// dismiss the popup window after 3sec
new Handler().postDelayed(new Runnable() {
public void run() {
pw.dismiss();
}
}, 3000);
}
xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toast_layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:orientation="vertical"
android:elevation="10dp"
android:padding="20dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFF"
android:textStyle="bold"/>
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFF"/>
</LinearLayout>
Upvotes: 4
Reputation: 5857
A 'Dialog' type of activity will probably be your best bet.
In manifest:
<activity android:name=".ToastLikeActivity"
android:theme="@android:style/Theme.Dialog"
android:label="@string/label"
></activity>
And timeout the activity within the onCreate():
class ToastLikeActivity extends Activity {
@Override
public void onCreate(Bundle state)
// auto-kill activity after X seconds <-------------------------
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
ToastLikeActivity.this.finish(); // kill after X seconds
}
}
}, VisibleTimeSecs*1000);
}
To display the dialog start it as with any other activity:
Intent i = new Intent(this, ToastLikeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
And it will show up and automatically go away after X seconds.
Such a popup will not be tied to the caller activity. In fact - it will not even require a caller activity. You can activate it (bad idea, but possible) even from a service.
You can implement basically any kind of sensitive (i.e. accepting user's clicks) interface you want to the ToastLikeActivity. Especially: you can make its exteriors transparent, giving it a dialog-likke looks.
Upvotes: 0
Reputation: 2424
I think what you need is in fact a PopupWindow
which can be seen here "http://developer.android.com/reference/android/widget/PopupWindow.html".
Toasts have a very specific task, which is to inform the user, without any input from them. So instead of trying to extend the purpose of the Toast, use the PopupWindow which can be interacted with by the user.
Upvotes: 0
Reputation: 3771
You are right, a Toast
object has no way to be interacted with, but there are many libraries out there that will give you the same look and feel as a toast, but with some interactivity. The one I use is https://github.com/JohnPersano/SuperToasts
Upvotes: 1