如何在显示前获取 Android Toast 的高度

3

我一直在尝试获取自定义Toast的高度,以便使用以下代码将Toast显示在按钮的右上角:

import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MyToast {

    public static void showToast(Context context, View v, String s) {

        int pos[] = new int[2];
        v.getLocationOnScreen(pos);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        View layout = inflater.inflate(R.layout.toast_style, (ViewGroup) v.findViewById(R.id.toast_layout_root));

        TextView text = (TextView) layout.findViewById(R.id.toast_text);
        text.setText(s);

        Toast toast = new Toast(context);
        toast.setGravity(Gravity.TOP|Gravity.LEFT, pos[0] + v.getWidth(), pos[1] - v.getHeight());
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.setView(layout);
        toast.show();
    }
}

我传递了按钮的视图,以便获取我想要放置toast的位置,但是v.getHeight()不是完成此任务所需的高度,有什么建议吗?

这是xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toast_layout_root"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="8dp"
    android:background="@drawable/frame_outline" >

    <TextView
        android:id="@+id/toast_text"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:textStyle="italic"
        android:textSize="12sp"
        android:typeface="serif"
        android:gravity="center"
        android:textColor="@color/holo_text" />

</LinearLayout>

我尝试使用text.getHeight()和layout.getHeight(),但两者都返回零。 - Raddy
方法是在什么时候被调用的?也许视图还没有被绘制出来? - Marco Acierno
我能否检索正在创建的视图的高度?它不应该必须显示才能有高度。 - Raddy
@Raddy,请发布你的XML。 - Rod_Algonquin
即使我已经很久没有开发Android了,但我确信Android在绘制View之前不会向您报告其高度/宽度。如果View没有显示出来,Android就不会绘制它,因为这是无用的。 - Marco Acierno
我猜那样做有道理,但我能不能找到一种方法让它工作呢? - Raddy
1个回答

1
你可以使用ViewTreeObserver来获取textView的高度,而不需要在屏幕上显示它,通过调用getViewTreeObserver方法并在ViewTreeObserveronGlobalLayout方法中获取高度。
final TextView text = (TextView) layout.findViewById(R.id.toast_text);
          text.setText(s);
          final ViewTreeObserver observer= text.getViewTreeObserver();
           observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                 Log.d("Hieght", ""+text.getHeight());   
                }
            });
         Toast

编辑:

您需要使用textView的post方法同步记录高度

  final TextView text = (TextView) layout.findViewById(R.id.toast_text);
          text.setText(s);
          final ViewTreeObserver observer= text.getViewTreeObserver();
           observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                 hieght = text.getHeight();   
                }
            });
  text.post(new Runnable() {

        @Override
        public void run() {
             Log.d("Hieght", ""+hieght); //hieght is the variable you used to get the height in the onGlobalLayout

        }
    });

看起来工作正常,值应该是正确的,但我无法从onGlobalLayout()函数中获取高度,我该怎么做?我尝试在函数外创建一个变量,但无法存储它。 - Raddy
我使用了一个静态变量,成功获取了高度值,之前由于某些原因无法获取。不管怎样,我尝试在文本中使用换行符输入不同的高度值来制作Toast,但是它没有给出正确的位置,Toast浮动了一段距离,我得到的高度值与Toast的高度不匹配,而且第一次按下按钮总是会给出高度=0。 - Raddy
@Raddy,Toast 中有一些填充,因此您不会真正获得所需的正确高度,您需要从 Toast 中添加顶部和底部填充。 - Rod_Algonquin
哦,好的,我明白你的意思了,但是我该如何将8dp转换为像素?我正在使用三星Galaxy SII,分辨率为480x800。 - Raddy
好的,我用了24,它给出了正确的结果,但仍然有一个问题,在第一次按下按钮时,高度总是为零。 - Raddy
确保在回调函数中删除监听器,否则会导致内存泄漏。 - Christopher Perry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接