custom Toast at screen top
Asked Answered
C

4

6

Please read the question before answering with your standard routine to print a Toast :)

I'd like to display a Custom Toast at the top left corner of the screen. I use this code to create the Toast:

    Toast mFixedToast = new Toast(getApplicationContext());
    mFixedToast.setDuration(timeout);
    mFixedToast.setView(myInflatedLayout);
    mFixedToast.setGravity(Gravity.TOP|Gravity.FILL_HORIZONTAL, 0, 0);
    mFixedToast.setMargins(0,0);

However, in some devices, for example Samsung Galaxy S4, the toast is not positioned at (0,0), but with a margin like 40-50 pixels. Many other devices work as expected.

I am positive the margin is added by the WindowManager (The toast view is added as a View of type TYPE_TOAST to the WindowManager)

Why is that? Can it be modified? Please see the code below, I've cloned Toast.java into my own class and isolated the lines where the View is added to the WM:

 // LayoutParams for the TOAST view ... tried to change params.type but no luck.
 final WindowManager.LayoutParams params = mParams;
 params.height = WindowManager.LayoutParams.WRAP_CONTENT;
 params.width = WindowManager.LayoutParams.WRAP_CONTENT;
 params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
              | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
            params.format = PixelFormat.TRANSLUCENT;
 params.windowAnimations = android.R.style.Animation_Toast;
 params.type = WindowManager.LayoutParams.TYPE_TOAST;

 mWM = (WindowManager)mView.getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
 mParams.gravity = gravity;

 // CHECKED these all are 0 !!!
 mParams.x = mX; mParams.y = mY;
 mParams.verticalMargin = mVerticalMargin;
 mParams.horizontalMargin = mHorizontalMargin;
 .
 .
 if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this+" with "+mX+","+mY+","+mVerticalMargin+","+mHorizontalMargin);
 mWM.addView(mView, mParams);

So it looks like it's the WindowManager who is adding this margin on those devices. Looks like a safe area or something like that, but I cant find where (or if) this can be changed.

Help appreciated.

Cyndycynera answered 18/11, 2014 at 6:53 Comment(2)
I've noticed the space at the top is 4.0+ devices. Did you ever figure out how to solve this?Fantasy
Never mind, figured this out, see my response below.Fantasy
F
3

I figured this out.

Starting 4.4+ you have to add the following flag:

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
        mParams.flags = mParams.flags | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
}

This will allow your toast to be positioned all the way to the top.

Fantasy answered 28/5, 2015 at 6:20 Comment(0)
P
1

Please try the following :

mFixedToast.setGravity(Gravity.TOP, 0, 0);

Also check the inflated layout, that might be causing the issue. You might be using the MatchParent for that view and gravity center.

Phillips answered 18/11, 2014 at 7:1 Comment(1)
As you see in the question, The gravity already has TOP besides FILL_HORIZONTAL (although it doesn't work either with TOP only). The inflated layout is positively not causing the issue (is a mere SingleLine TextView without padding or margin)Cyndycynera
T
0
private void Toast(String string) {
        // TODO Auto-generated method stub
        LinearLayout layout = new LinearLayout(this);
        layout.setBackgroundResource(R.color.Orange);
        TextView tv = new TextView(this);
        tv.setTextColor(Color.YELLOW);
        tv.setTextSize(25);
        tv.setGravity(Gravity.Top);
        tv.setText(string);
        ImageView img = new ImageView(this);
        img.setImageResource(R.drawable.ic_launcher2);
        layout.addView(img);
        layout.addView(tv);
        Toast toast = new Toast(this); // context is object of Context write
        tts.speak(string, TextToSpeech.QUEUE_FLUSH, null); // "this" if you are
                                                            // an Activity
        toast.setView(layout);
        toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
        toast.show();
    }
Troup answered 18/11, 2014 at 7:12 Comment(1)
thanks for your implementation of a talking toast but it is not related to my problem!Cyndycynera
U
0

You can try this method to display toast in center of screen. If you want to display toast on top.you can change the msg.getYOffset(). Here is code. Try this

public static void displyToast(Context c, String str) {
        Toast msg = Toast.makeText(c, str, Toast.LENGTH_SHORT);
        msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2,
                msg.getYOffset() / 2);
        msg.show();
    }

msg.getXOffset() / 2 take toast on center of screen horizintallly, whereas `msg.getYOffset() / 2` takes toast on center of screen vertically.

I hope this will help you. Happy Coding :)

Undershorts answered 18/11, 2014 at 7:43 Comment(1)
As I stated in the question, setting margin parameters to 0 don't work because the windowmanager adds the margin itself.Cyndycynera

© 2022 - 2024 — McMap. All rights reserved.