Binary XML Inflate Error on PopupMenu.show() Android 在 Android 上,在 PopupMenu.show() 上发生二进制 XML 解析错误。

11 浏览
0 Comments

Binary XML Inflate Error on PopupMenu.show() Android 在 Android 上,在 PopupMenu.show() 上发生二进制 XML 解析错误。

当RecyclerView项被长按时,我想要展示一个简单的PopupMenu以供重命名/删除选项。但是当我将xml文件加载到inflater中后,当我调用mPopup.show()时,出现了XML inflate错误的问题。\n我在我的应用程序的其他地方使用类似的逻辑创建一个PopupMenu,并且它正常工作。我甚至尝试将工作正常的PopupMenu从应用程序的其他部分加载到这个inflater中,但是在logcat中我看到了相同的android.view.InflateException错误,所以可能不是XML文件的问题?\n如何让这个PopupMenu展开并显示出来?\n致命异常Logcat\n05-31 23:02:27.421 19597-20019/? E/AndroidRuntime: FATAL EXCEPTION: main\n Process: com.example.foo, PID: 19597\n android.view.InflateException: Binary XML file line #17: Failed to resolve attribute at index 1: TypedValue{t=0x2/d=0x7f01005d a=-1}\n Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 1: TypedValue{t=0x2/d=0x7f01005d a=-1}\n at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:761)\n at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:7060)\n at android.view.ViewGroup$MarginLayoutParams.(ViewGroup.java:7241)\n at android.widget.FrameLayout$LayoutParams.(FrameLayout.java:438)\n at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:370)\n at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:369)\n at android.view.LayoutInflater.inflate(LayoutInflater.java:505)\n at android.view.LayoutInflater.inflate(LayoutInflater.java:426)\n at android.support.v7.view.menu.MenuAdapter.getView(MenuAdapter.java:93)\n at android.support.v7.view.menu.MenuPopup.measureIndividualMenuWidth(MenuPopup.java:160)\n at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:153)\n at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:187)\n at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)\n at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:175)\n at android.support.v7.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:141)\n at android.support.v7.widget.PopupMenu.show(PopupMenu.java:233)\n at com.example.foo.FragmentChordMenu.showChordOptionsMenu(FragmentChordMenu.java:132)\n at com.example.foo.CustomChordAdapter$ChordViewHolder$2.onLongClick(CustomChordAdapter.java:138)\n at android.view.View.performLongClickInternal(View.java:5687)\n at android.view.View.performLongClick(View.java:5645)\n at android.view.View.performLongClick(View.java:5663)\n at android.view.View$CheckForLongPress.run(View.java:22234)\n at android.os.Handler.handleCallback(Handler.java:751)\n at android.os.Handler.dispatchMessage(Handler.java:95)\n at android.os.Looper.loop(Looper.java:154)\n at android.app.ActivityThread.main(ActivityThread.java:6077)\n at java.lang.reflect.Method.invoke(Native Method)\n at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)\n at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)\nFragmentActivity\npublic class FragmentChordMenu extends Fragment implements CustomChordAdapter.onItemClickListener { \n private static RecyclerView mCustomChordList;\n private static CustomChordAdapter mRecyclerViewAdapter;\n private static Context mContext;\n private FloatingActionButton mFAB;\n private View mPopupView;\n private PopupWindow mCustomChordMenu;\n @Override\n public void onActivityCreated(@Nullable Bundle savedInstanceState) {\n super.onActivityCreated(savedInstanceState);\n mRecyclerViewAdapter = new CustomChordAdapter(this);\n }\n @Nullable\n @Override\n public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {\n mContext = getActivity().getApplicationContext(); //为后来在fragment中使用而存储应用程序上下文,以防分离的风险\n //无风险\n View v = inflater.inflate(R.layout.menu_fragment_chord, container, false);\n LayoutInflater layoutInflater = (LayoutInflater)getActivity().getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);\n ...\n mFAB = (FloatingActionButton) v.findViewById(R.id.addChord);\n mFAB.setOnClickListener(new View.OnClickListener() {\n public void onClick(View v) {\n mCustomChordMenu.showAtLocation(mPopupView, Gravity.CENTER, 10, 10);\n mCustomChordList = (RecyclerView) mPopupView.findViewById(R.id.rv_userChords);\n LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());\n mCustomChordList.setLayoutManager(layoutManager);\n mCustomChordList.setAdapter(mRecyclerViewAdapter);\n }\n });\n return v;\n }\n public static void showChordOptionsMenu(final int position){\n View anchorView = mCustomChordList.findViewHolderForAdapterPosition(position).itemView;\n PopupMenu mPopup = new PopupMenu(mContext, anchorView);\n mPopup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {\n @Override\n public boolean onMenuItemClick(MenuItem item) {\n switch (item.getItemId()){\n case R.id.delete:\n mRecyclerViewAdapter.deleteChord(position);\n return true;\n case R.id.rename:\n Log.d(\"FragmentChordMenu: \", \"Rename clicked\");\n }\n return true;\n }\n });\n MenuInflater popupInflater = mPopup.getMenuInflater();\n popupInflater.inflate(R.menu.popup_delete_chord, mPopup.getMenu());\n mPopup.show(); //错误发生在这里\n }\n ...\n}\nPopupMenu XML\n\n

\n \n \n

\nFragmentActivity XML\n\n\n \n \n \n \n \n \n \n

0
0 Comments

在Android中出现了一个(Binary XML Inflate Error on PopupMenu.show() Android)的问题。这个问题的出现的原因是在使用appcompat-v7的PopupMenu时,使用了应用程序的Context。这个Context没有正确设置v7小部件的主题资源,导致了InflateException异常。然而,Activity拥有适当的主题,使用它可以解决这个特定的问题。

解决了这个问题后,又出现了一个WindowManager$BadTokenException异常,这是由于PopupMenu从PopupWindow中传递了一个锚定的View。弹出窗口必须锚定到顶层窗口中的一个View,而Popup*类基本上是简单的View,因此会出现异常。一个简单的解决方法是将PopupWindow替换为Dialog,它有一个Window。例如:

AlertDialog dlg = new AlertDialog.Builder(getActivity()).setView(mPopupView).show();

最后,建议您修改设置以消除在Fragment类中使用静态成员的需要。这些静态字段很可能会导致内存泄漏,并且您的IDE可能会警告您。一个类似于CustomChordAdapter中的监听器接口就足够了。

关于您答案的最后部分,我想了解更多信息;您有关于预防静态成员内存泄漏的资源链接吗?

嗯,并没有。我的意思是,只有两种方法可以避免这种内存泄漏:1)不使用它们。2)确保在使用完之后将引用设置为null。如果您只是想了解一般的静态泄漏和类似的信息,已经有很多相关文章了。这里有一些站内帖子,但您可能会在一些博客或教程等地方找到更详细的解释:stackoverflow.com/a/11908685stackoverflow.com/a/641473stackoverflow.com/a/28091135。最后一个链接中有一个指向旧的Android Developers Blog页面的链接。

救了我的一天,非常感谢。当我尝试在我的适配器中填充一个布局时,我遇到了类似的问题,读完您的评论后,我意识到我是用应用程序的Context而不是Activity的Context创建了这个适配器。

0