Show toast widget underneath a view

For those who helped me out earlier regarding this project, thank you very much! My code no longer has any problems, and I made extra tweaks. Now that the app is actually robust now, I want to do one more thing.

See screenshot of the layout here.

Normally, the toast view appears at the bottom center of the screen. I want to make it appear just below (8dp) the Submit button once OnClick is called. How can I accomplish this.

See my updated complete project here.

package com.lookjohn.guessnumber;

import java.util.Random;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
Random random; 
Button button;
EditText text;

int input; 
int MIN, MAX;
int comp; 
int guesses;

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    random = new Random();
    button = (Button)findViewById(R.id.button1);
    text = (EditText)findViewById(R.id.editText1);

    MIN = 1;
    MAX = 100;
    comp = random.nextInt(MAX - MIN + 1) + MIN; // Generate random number between 1 and 100.
    guesses = 0;

    button.setOnClickListener(myhandler1);
}

View.OnClickListener myhandler1 = new View.OnClickListener() {

    public void onClick(View v) {

        // Implemented max number of guesses, detect 
        // number of guesses and return from the method.

        String value = text.getText().toString(); // Get value from input from editTextView

        // If user submits an empty EditText, return to prevent a crash.
        if (value.isEmpty()) {
            Toast.makeText(MainActivity.this, "You must enter a guess!", Toast.LENGTH_SHORT);
            return;
        }

        input = Integer.parseInt(value); // Turn string into integer
        guesses++;
        if (input > 100) {
            Toast.makeText(MainActivity.this, 
                "That number is greater than 100. Not Valid!", 
                Toast.LENGTH_SHORT).show();
                return;
            }

        else if (input < comp)
            Toast.makeText(MainActivity.this, 
                "Your number is too small.", 
                Toast.LENGTH_SHORT).show();
        else if (input > comp) 
            Toast.makeText(MainActivity.this, 
                "Your number is too big.", 
                Toast.LENGTH_SHORT).show();
        else
            Toast.makeText(MainActivity.this, 
                "Good job! The answer was " + comp + ".\n" +
                "You made " + guesses + " guesses.\n" +
                "Restart the app to try again.", 
                Toast.LENGTH_LONG).show();
    }
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

android.widget.Toast defines a bunch of useful methods that allow customizing look and feel of a toast notification. Method you should look into is setGravity(int, int, int). With 0 offsets code below will anchor toast top to the bottom of the provided view and toast center to the center of the view.

public static void positionToast(Toast toast, View view, Window window, int offsetX, int offsetY) {
    // toasts are positioned relatively to decor view, views relatively to their parents, we have to gather additional data to have a common coordinate system
    Rect rect = new Rect();
    window.getDecorView().getWindowVisibleDisplayFrame(rect);
    // covert anchor view absolute position to a position which is relative to decor view
    int[] viewLocation = new int[2];
    view.getLocationInWindow(viewLocation);
    int viewLeft = viewLocation[0] - rect.left;
    int viewTop = viewLocation[1] - rect.top;

    // measure toast to center it relatively to the anchor view
    DisplayMetrics metrics = new DisplayMetrics();
    window.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int widthMeasureSpec = MeasureSpec.makeMeasureSpec(metrics.widthPixels, MeasureSpec.UNSPECIFIED);
    int heightMeasureSpec = MeasureSpec.makeMeasureSpec(metrics.heightPixels, MeasureSpec.UNSPECIFIED);
    toast.getView().measure(widthMeasureSpec, heightMeasureSpec);
    int toastWidth = toast.getView().getMeasuredWidth();

    // compute toast offsets
    int toastX = viewLeft + (view.getWidth() - toastWidth) / 2 + offsetX;
    int toastY = viewTop + view.getHeight() + offsetY;

    toast.setGravity(Gravity.LEFT | Gravity.TOP, toastX, toastY);
}

Using it will require modifying toast related lines in your onClick method:

int offsetY = getResources().getDimensionPixelSize(R.dimen.toast_offset_y);

Toast toast = Toast.makeText(MainActivity.this, "That number is greater than 100. Not Valid!", Toast.LENGTH_SHORT);
positionToast(toast, v, getWindow(), 0, offsetY);
toast.show();

For your question, as to how to show a toast at a specific position ,you can do this :-

Toast toast = new Toast();
toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0);
toast.makeText(getApplicationContextt(),"Text",Toast.LENGTH_SHORT);
toast.show();

You can make modifications in this like of code to change toast position :-

    toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0);

From developer guide, you can position your Toast using toast.setGravity(). I find this on http://developer.android.com/guide/topics/ui/notifiers/toasts.html

Positioning your Toast A standard toast notification appears near the bottom of the screen, centered horizontally. You can change this position with the setGravity(int, int, int) method. This accepts three parameters: a Gravity constant, an x-position offset, and a y-position offset.

For example, if you decide that the toast should appear in the top-left corner, you can set the gravity like this:

toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0); If you want to nudge the position to the right, increase the value of the second parameter. To nudge it down, increase the value of the last parameter.

I think you can get position of your button and forward it to mentioned method


None of the answers did the job to me, i made a combination of the above answers and I got the solution down.

enter image description here

The second timer is the target view.

 public static void displayToastUnderView(Activity activity, View view, String text) {
        Toast toast = Toast.makeText(activity, text, Toast.LENGTH_SHORT);
        toast.setGravity( Gravity.TOP, view.getLeft() - view.getWidth() / 2 - toast.getView().getWidth() / 2, view.getBottom());
        toast.show();
    }

I would just like to add to solmaks answer.

in positionToast:

    ...
    int toastHeight= toast.getView().getMeasuredHeight();

    // compute toast offsets
    ...
    int toastY = viewTop + (view.getHeight() - toastHeight) / 2 + offsetY;

in onClick:

    positionToast(toast, view, getWindow(), 0, 0);  

This seems to center the Toast perfectly in my view, no matter where the view is placed. There is an assumption in my code that the Toast will always be smaller than the view it is in.