我想在用户点击浮动图标时显示自定义弹出菜单
使用服务创建浮动图标,我没有活动
这是我的浮动图标代码
public class copy_actions_service extends Service
{
ImageView copy_ImageView;
WindowManager windowManager;
WindowManager.LayoutParams layoutParams;
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate()
{
windowManager=(WindowManager)getSystemService(WINDOW_SERVICE);
copy_ImageView=new ImageView(this);
copy_ImageView.setImageResource(R.drawable.ic_launcher);
copy_ImageView.setAlpha(245);
copy_ImageView.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
showCustomPopupMenu();
}
});
layoutParams=new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
layoutParams.gravity=Gravity.TOP|Gravity.CENTER;
layoutParams.x=0;
layoutParams.y=100;
windowManager.addView(copy_ImageView, layoutParams);
}
private void showCustomPopupMenu()
{
LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=layoutInflater.inflate(R.layout.xxact_copy_popupmenu, null);
PopupWindow popupWindow=new PopupWindow();
popupWindow.setContentView(view);
popupWindow.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
}
}
每件事情都很好但是当我点击浮动按钮app停止并且这个错误显示在logcat上:(
11-23 02:18:58.217: E/AndroidRuntime(3231): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
但我没有活动?!
我想在用户点击浮动图标后弹出菜单显示;但弹出菜单只能显示文字;
如何显示带图标的弹出菜单?
答案 0 :(得分:26)
如果您正在使用Context
作为Dialog dialog = new Dialog(getApplicationContext());
来进行此类对话
Dialog dialog = new Dialog(YourActivityName.this);
然后使用YourActivityName.this
_
答案 1 :(得分:9)
我遇到了和你一样的问题,看起来你像我一样使用了http://www.piwai.info/chatheads-basics的教程。问题是您无法将当前活动可靠地传递到弹出窗口,因为您无法控制当前活动。看起来可能有一种不可靠的方式来获取当前活动,但我不建议这样做。
我为我的应用程序修复它的方法是不使用弹出窗口,而是通过窗口管理器自行创建。
private void showCustomPopupMenu()
{
windowManager2 = (WindowManager)getSystemService(WINDOW_SERVICE);
LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=layoutInflater.inflate(R.layout.xxact_copy_popupmenu, null);
params=new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity=Gravity.CENTER|Gravity.CENTER;
params.x=0;
params.y=0;
windowManager2.addView(view, params);
}
如果您希望它看起来像一个弹出窗口,只需添加一个透明的灰色视图作为背景,并向其添加一个onClickListener以从windowManager对象中删除该视图。
我知道这不像弹出窗口那么方便,但根据我的经验,这是最可靠的方式。
并且不要忘记在清单文件中添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
答案 2 :(得分:6)
当您尝试过早显示popUpWindow来解决此问题时,会发生此错误,要对其进行修复,请将ID设置为main_layout
并使用下面的代码
Java:
findViewById(R.id.main_layout).post(new Runnable() {
public void run() {
popupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0);
}
});
科特琳:
main_layout.post {
popupWindow?.showAtLocation(main_layout, Gravity.CENTER, 0, 0)
}
贷记@kordzik
答案 3 :(得分:5)
您需要在构造函数中传递您的活动
PopupWindow popupWindow = new PopupWindow(YourActivity.this)
答案 4 :(得分:4)
如果您使用另一个 view
,请确保使用 view.getContext()
而不是 this
或 getApplicationContext()
答案 5 :(得分:3)
使用此Dialog dialog = new Dialog(theActivity.this);
代替Dialog dialog = new Dialog(getApplicationContext);
或Dialog dialog = new Dialog(context);
答案 6 :(得分:1)
PopupWindow
只能附加到Activity
。在您的情况下,您尝试将PopupWindow
添加到service
,这是不对的。
要解决此问题,您可以使用空白且透明的Activity
。点击浮动图标,启动Activity
并onCreate
Activity
显示PopupWindow
。
在解雇PopupWindow
时,您可以finish
透明Activity
。
希望这会对你有所帮助。
答案 7 :(得分:1)
您不应将windowManager.addView放在onCreate中
尝试在windowManager.addView
之后调用onWindowFocusChanged
,并且hasFoucus
的状态为true。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//code here
//that you can add a flag that you can call windowManager.addView now.
}
答案 8 :(得分:1)
尝试显示DatePicker
中的Fragment
时出现此错误。
我改变了
val datePickerDialog = DatePickerDialog(activity!!.applicationContext, ...)
到
val datePickerDialog = DatePickerDialog(requireContext(), ...)
效果很好
答案 9 :(得分:1)
在我的情况下,我在活动开始时就对PopupMenu进行了膨胀,即在onCreate()上...通过将其放入 Handler
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
PopupMenu popuMenu=new PopupMenu(SplashScreen.this,binding.progressBar);
popuMenu.inflate(R.menu.bottom_nav_menu);
popuMenu.show();
}
},100);
答案 10 :(得分:0)
我遇到了同样的问题,我已经通过@Redman的解决方案和其他一些方法解决了这个问题,
这就是我所做的。
findViewById(R.id.main_layout).post(new Runnable() {
public void run() {
popupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0);
}
});
添加了Runnable方法,并在onDestroy方法中检查了popuwindow是否显示为空。
@Override
protected void onDestroy() {
super.onDestroy();
if (popupWindow.isShowing())
{
popupWindow.dismiss();
popupWindow=null;
}
}
答案 11 :(得分:0)
使用YOURACTIVITY.this代替getApplicationContext()
答案 12 :(得分:0)
此错误是由于传递了错误的上下文引起的。
您必须将“活动”作为上下文传递,getApplicationContext()
不起作用。
因此,将您的上下文投射到“活动”。
在科特林,
context as HomeActivity
答案 13 :(得分:0)
如果您将getBaseContext()或getApplicationContext()用作此类对话框的上下文
Dialog dialog = new Dialog(getBaseContext());
或
Dialog dialog = new Dialog(getApplicationContext());
然后使用YourActivityName.this
对话框对话框=新对话框(YourActivityName.this);