【Android】popup windows 的使用方式 和 遇到不显示的坑
主题观点:在Android开发中,使用PopupWindow组件时,正确处理布局宽高的WRAP_CONTENT和MATCH_PARENT设置是确保UI正确展示的关键。
引言
在Android应用开发中,PopupWindow是一个非常有用的组件,用于在当前Activity中显示一个浮动的视图,如提示信息、菜单或其他操作选项。然而,如果不正确设置PopupWindow的大小,可能会导致视图显示不完全或者根本不显示。
相关问题与解答
问题1:为什么我的PopupWindow设置的宽高是WRAP_CONTENT,但它没有显示出来?
解答1:在父容器是Dialog这样的布局中,如果内部布局的宽高设置为MATCH_PARENT,而外部布局设置为WRAP_CONTENT,可能会导致内部视图无法正确扩展到整个父容器的大小。此外,如果内部布局再次使用WRAP_CONTENT,这将进一步限制视图的大小,可能导致显示不全。
问题2:如何在Dialog布局中正确设置PopupWindow的大小?
解答2:在创建PopupWindow时,确保内部视图的布局也采用WRAP_CONTENT作为宽高的设置。这样可以确保视图能够根据其内容的大小自动调整。例如:
view.addView(popupWindow.getContentView(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
同时,确保外部布局(如Dialog布局)不对视图大小进行额外的限制,或者使用MATCH_PARENT以允许内部视图完全扩展。
问题3:还有哪些情况可能导致PopupWindow不显示?
解答3:除了布局设置不当,还有其他可能导致PopupWindow不显示的因素,如:
- PopupWindow未被正确显示前重复调用PopupWindow的显示方法。
- PopupWindow的父容器设置为非可见状态,如Dialog未显示时就调用show方法。
- PopupWindow的创建时机过早,应在UI线程中创建。
通过避免这些陷阱并正确调整布局和代码,可以确保PopupWindow在Android应用中正确且一致地显示。
背景
在项目开发过程中有一个需求就是点击一个问号icon 弹出相关提示信息在下面,那么就得对这个做适配了。
计划采用popupWindow 实现:
参考
实现
基本的套路就是写一个xml对应的布局,然后在java 层使用即可。
特别注意的是该xml布局要慎重:尤其是宽高设置(下图是正确设置)
问题是在dialog 对象内实现对popup操作,但是似乎没有显示出来
原来就是上面说的布局
我在dialog对象中对上述的xml 是采用wrap的方式对待宽高。
popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
这个layout和TextView都要wrap
你外层说wrap,内部说matchparent,那系统怎么算你大小
外面说按里面来,里面说按外面来,所以就默认为0
所以就没有展示出来。
详细代码
下面附上详细的正确的代码
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;/* 针对点击 问号 icon* 弹出相关tips 提示的控制类*/
public class TipPopupController {private PopupWindow popupWindow;private Context context;public TipPopupController(@NonNull Context context) {this.context = context;// 一个自定义的popup window布局,作为显示的内容View contentView = LayoutInflater.from(context).inflate(R.layout.fs_popup_window_common, null);popupWindow = new PopupWindow(contentView);}/* 启动弹窗(默认在视图的下面)* 内部自动管控 showing 时机* @param view 指定视图* @param tip 提示文本*/public void enablePopupWindow(View view, String tip) {// 避免重复点击出现if(popupWindow.isShowing()){popupWindow.dismiss();return;}popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);TextView tvTips = popupWindow.getContentView().findViewById(R.id.tv_tips);tvTips.setText(tip);popupWindow.setBackgroundDrawable(ResourcesCompat.getDrawable(context.getResources(),