Android开发:如何在点击的View上方显示Toast?
问题
Android应用的主Activity内包含多个ImageView,点击图片时会弹出用于说明该图片的Toast,其默认显示位置为屏幕底部。已知toast.setGravity(int, int, int)方法可调整Toast位置,但不清楚如何获取被点击View的位置,以此实现将Toast显示在该View的正上方。相关代码如下:
public class ShowLocationInfo extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_location_info); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); if (gNewMarinas[gChosenMarinaNr].isMarina) TAGstrings = getResources().getStringArray(R.array.feature_and_types_explanation_for_marinas); else TAGstrings = getResources().getStringArray(R.array.feature_and_types_explanation_for_anchoring); androidx.appcompat.widget.AppCompatImageView RON95ImageView = findViewById(R.id.ron95_imageview); RON95ImageView.setOnClickListener(v -> showExplanation(v, ShowLocationInfo.this)); if ((gNewMarinas[gChosenMarinaNr].typesAndFeatures & kRON95Bit) != 0) { RON95ImageView.setTag(TAGstrings[17]); RON95ImageView.setVisibility(View.VISIBLE); } else { RON95ImageView.setTag(TAGstrings[18]); RON95ImageView.setVisibility(View.VISIBLE); RON95ImageView.setImageResource(R.drawable.pump_95_grey); } } void showExplanation(View v, Context context){ if (v.getTag() != null) { Toast.makeText(context, v.getTag().toString(), Toast.LENGTH_SHORT).show(); } } }
解决方案
要实现Toast显示在被点击View的正上方,可通过以下步骤获取View位置并调整Toast布局:
1. 获取View的屏幕绝对坐标
使用getLocationOnScreen(int[])方法获取View左上角在屏幕中的坐标,数组索引0对应x坐标,索引1对应y坐标。
2. 计算Toast的偏移量
将Toast的gravity设置为Gravity.TOP | Gravity.CENTER_HORIZONTAL,再通过View的位置、尺寸和屏幕宽度计算偏移量,确保Toast水平居中于View上方,且与View保持适当间距。
修改后的showExplanation方法代码如下:
void showExplanation(View v, Context context){ if (v.getTag() != null) { Toast toast = Toast.makeText(context, v.getTag().toString(), Toast.LENGTH_SHORT); // 获取View在屏幕中的坐标 int[] location = new int[2]; v.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; // 获取屏幕宽度 DisplayMetrics metrics = context.getResources().getDisplayMetrics(); int screenWidth = metrics.widthPixels; // 提前测量Toast高度,避免获取到0值 toast.getView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); int toastHeight = toast.getView().getMeasuredHeight(); // 设置Toast位置:水平居中于View上方,预留10px间距 toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, viewX + v.getWidth()/2 - screenWidth/2, viewY - toastHeight - 10); toast.show(); } }
补充说明
getLocationOnScreen获取的是View相对于屏幕左上角的坐标,比getLocationInWindow更适配有状态栏的场景;- 提前调用
measure方法可以避免直接获取Toast高度时返回0的问题; - 代码中最后减去的
10是View与Toast之间的间距,可根据UI需求调整数值。
内容的提问来源于stack exchange,提问作者Tomas F.
相关产品推荐
相关产品推荐

