Is it possible to create a clickable Toast-like no

2019-07-23 07:16发布

I have a need to show a minimally-intrusive non-blocking notification which is not tied to the activity it was shown in (like a Toast) and which is clickable. Anyone have any idea whether or not this is possible? Unfortunately it appears Toast notifications (custom or otherwise) are not clickable (i.e. setting an OnClickListener on its views has no effect). And, correct me if I'm wrong, all the alternatives (AlertDialg, PopupWindow, Crouton) show a notification which is tied to the activity it was shown in (i.e. they won't continue showing when the activity finishes). Any suggestions?

4条回答
成全新的幸福
2楼-- · 2019-07-23 07:27

I think what you need is in fact a PopupWindowwhich 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.

查看更多
时光不老,我们不散
3楼-- · 2019-07-23 07:28

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>
查看更多
家丑人穷心不美
4楼-- · 2019-07-23 07:29

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

查看更多
迷人小祖宗
5楼-- · 2019-07-23 07:46

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.

查看更多
登录 后发表回答