在演示文稿显示中使用演示文稿上下文显示Toast消

时间:2016-02-22 10:45:11

标签: android

我想在主要显示和演示显示中显示两种不同的祝酒词。

我使用以下代码来显示吐司

Toast.makeText(getContext(), "No HDMI Connected", Toast.LENGTH_SHORT).show();

其中,getContext()如下

public Context getContext() {
        if (presentation != null) {   //presentation object
            return(presentation.getContext());
        }

        return(getActivity());
    }

问题是Toast未在演示显示中显示,这是一个HDMI屏幕。

如何实现这一目标任何帮助/暗示都非常有帮助......

谢谢。

1 个答案:

答案 0 :(得分:1)

如果不编写自己的Toast类,我认为这是不可能的。我查看了Toast的源代码,并从传递的上下文中获取了Application上下文,这就是为什么toast总是在主显示中呈现的原因:

来自Toast.java源代码(示例http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/4.4_r1-robolectric-0/android/widget/Toast.java

373        public void handleShow() {
.
.
380                Context context = mView.getContext().getApplicationContext();
.
384                mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
.
.
405                mWM.addView(mView, mParams);

好消息是,我自己编写了Toast的el-cheapo版本,固定在不同的显示器上运行。它不是替代品,也不是花哨的动画,但还有其他很酷的功能,如持久的吐司和自定义时间。您可以轻松自定义它以适应您的应用程序风格。

这就是:

package com.regaliz.custom;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.WindowManager;
import android.widget.TextView;

/**
 * A Toast-like class that can be used across different displays, 
 * and show permanent and custom-timed notifications.
 *
 * Rodolfo Lopez 2016 - Freeware 
 *
 * Usage:
 * 
 * 1) Create the object: 
 *
 *    Tostada mTostada = new Tostada(Gravity.BOTTOM|Gravity.CENTER_VERTICAL, 0, 50);
 *
 * 2) Assign a context. You can dynamically change the context to 
 * the Tostada object in the case of a display change without the
 * need to create another object.
 *
 *    mTostada.setContext(context);
 *
 * 3) Start toasting!
 *
 *    mTostada.makeText("hi!", Toast.LENGTH_SHORT);
 *    mTostada.makeText("hi!", 0);
 *    - You can use "0" to make the Toast persistent
 *    - Toasts are NOT QUEUED: If a toast is visible, the text will
 * be replaced and the new timeout set. This just fits my use case.
 * 
 * 4) call setContext(null) in the case of multi-context use, 
 * for example, when you close a presentation display, so a 
 * reference to an invalid context is not kept. Or just change to 
 * a valid context.
 *
 */

public class Tostada {

    private TextView mView;
    private WindowManager mWM;
    private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
    private Context mContext;

    /**
     * Creates a Tostada with a gravity ana an offset x, y
     *
     * @param offsetX The X offset in pixels to apply to the gravity's location.
     * @param offsetY The Y offset in pixels to apply to the gravity's location.
     * @paran gravity The gravity constant
     */

    public Tostada(int gravity, int offsetX, int offsetY) {

        final WindowManager.LayoutParams params = mParams;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.format = PixelFormat.TRANSLUCENT;
        params.windowAnimations = 0;
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.setTitle("Toast");
        params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

        mParams.gravity = gravity;
        mParams.x = offsetX;
        mParams.y = offsetY;
        mParams.verticalMargin = 0;
        mParams.horizontalMargin = 0;

    }

    /**
     * Assign the Tostada context. It can be a Presentation context. Remember to call setContext(null)
     * to clear the stored context when you no longer need this class, otherwise memory leaks can occur.
     *
     * @param context The context where the Tostada will be rendered
     */

    public void setContext(Context context) {

        if (mContext != null) {
            if (mContext == context) {
                // re - assigning same context, just return
                return;
            }
            handleHide();
        }

        mContext = context;

        if (context == null) {

            mView = null;
            return;
        }

        mParams.packageName = context.getPackageName();

        // I use a plain TextView with default styling.
        // you can customize it here

        mView = new TextView(context);

        mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

    }

    private Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            handleHide();
        }
    };

    public void makeText(String text, int timeout) {

        if (mContext == null)
            throw new IllegalStateException("You must assign a context to this Tostada before it vcan be used");

        // remove old timer for an ongoing tostada, if any
        mView.removeCallbacks(mHideRunnable);

        mView.setText(text);

        // Add the view to the window manager, if not already added
        if (mView.getParent() == null)
            mWM.addView(mView, mParams);

        // schedule for removal

        if (timeout > 0)
            mView.postDelayed(mHideRunnable, timeout);
    }

    private void handleHide() {

        // remove the view if added
        if (mView.getParent() != null)
            mWM.removeView(mView);

    }

}