避免将 null 作为视图根传递(需要在膨胀布局的根元素上解析布局参数)
Posted
技术标签:
【中文标题】避免将 null 作为视图根传递(需要在膨胀布局的根元素上解析布局参数)【英文标题】:Avoid passing null as the view root (need to resolve layout parameters on the inflated layout's root element) 【发布时间】:2014-09-10 00:49:03 【问题描述】:为 root studio 传递 null 会给我这个警告:
它在getGroupView
中显示一个空值。请帮忙。
public class ExpandableListAdapter extends BaseExpandableListAdapter
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData)
super();
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
@Override
public Object getChild(int groupPosition, int childPosititon)
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
@Override
public long getChildId(int groupPosition, int childPosition)
return childPosition;
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null)
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
TextView txtListChild = (TextView) convertView
.findViewById(R.id.lblListItem);
txtListChild.setText(childText);
return convertView;
@Override
public int getChildrenCount(int groupPosition)
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
@Override
public Object getGroup(int groupPosition)
return this._listDataHeader.get(groupPosition);
@Override
public int getGroupCount()
return this._listDataHeader.size();
@Override
public long getGroupId(int groupPosition)
return groupPosition;
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent)
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null)
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
@Override
public boolean hasStableIds()
return false;
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
return true;
【问题讨论】:
【参考方案1】:而不是做
convertView = infalInflater.inflate(R.layout.list_item, null);
做
convertView = infalInflater.inflate(R.layout.list_item, parent, false);
它将使用给定的父级对其进行膨胀,但不会将其附加到父级。
【讨论】:
@Coeffect 但是从 Activity 中充气时应该使用什么?我应该用什么代替父母? @AlexanderKuznetsov 取决于你想要做什么,我想。如果您尝试设置活动的内容,您应该使用setContentView(layoutId)
。如果您尝试向现有 ViewGroup 添加新视图,您可能应该只传递父视图并让充气器附加新视图。
@LucasTan 我想我会在 TabContentFactory 中保留对 TabHost 的引用,并在充气时将其用作父级,但我不确定这是否是最佳解决方案。奇怪的是 createTabContent 方法不提供父/上下文。
在为InputMethodService
实现onCreateInputView()
时会出现同样的问题(没有父级)。
alertdialog 的自定义视图怎么样,parent 应该是什么?【参考方案2】:
我发现了一篇关于LayoutInflater
的好文章。作者解释了inflate
方法的所有版本是如何工作的,并给出了ListView
和AlertDialog
的例子
http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
更新 #1。
这个答案最近也帮助了我。 https://***.com/a/5027921/1065835
【讨论】:
【参考方案3】:来吧,由于某种原因,使用 View.inflate 而不是从 layoutinflater 膨胀会使 lint 错误消失。 我想我会在这里发布这个帖子,因为这个帖子在谷歌搜索的顶部......
view = View.inflate(context,R.layout.custom_layout,null);
【讨论】:
这消除了 Lint 警告,但不是问题本身,因为 View.inflate() 在后台调用 LayoutInflater。您应该修复原因,而不仅仅是删除消息。【参考方案4】:编辑:
在撰写此答案时,我不知道 Lint 抑制。最好抑制 Lint 而不是欺骗 IDE。在行或方法上方添加:
@SuppressLint("InflateParams")
旧答案:
当你真的没有parent
时(例如为AlertDialog
创建视图),除了传递null
之外别无他法。所以这样做是为了避免警告:
final ViewGroup nullParent = null;
convertView = layoutInflater.inflate(R.layout.list_item, nullParent);
【讨论】:
与其欺骗 lint 工作,不如进行抑制。 我不确定这个答案是否正确。我成功使用了ViewGroup root = (ViewGroup) myActivity.findViewById(R.id.my_main_content);
,其中my_main_content
是我的活动布局文件中最外层容器的ID。
要禁止这个 Lint,在你的方法上方添加 @SuppressLint("InflateParams")
。
我发现@ban-geoengineering 回复是最有帮助的,它既消除了消息又解决了问题。这是对我有用的 Kotlin 解决方案。 val rootView = findViewById<ViewGroup>(R.id.container)
.... imageHolder = vInflater.inflate(R.layout.recycler_view_target, rootView,false)
这让我可以在 RecyclerView Holder 中放置不同的视图。【参考方案5】:
AlertDialog
可以使用下面的代码
convertView = layoutInflater.inflate(R.layout.list_item, findViewById(android.R.id.content), false);
【讨论】:
【参考方案6】:我在寻找解决此问题的方法时发现了一个很好的信息。根据 Dave Smith 的说法,
布局膨胀是在 Android 上下文中使用的术语,用于指示 XML 布局资源何时被解析并转换为 View 对象的层次结构。
这里要求ViewGroup
作为 inflate 方法参数的一部分用于继承更高级别的样式。虽然传递 null 看起来无害,但它实际上可能会在以后给您的应用程序带来严重问题。阅读更多关于此here 的信息。
【讨论】:
【参考方案7】:这是一张供参考的图片:
return inflater.inflate(R.layout.some_layout, container, true);
// for the last parameter use true, false or simply don't declare
【讨论】:
顺便...导入ANDROIDX.fragment.app.Fragment;以上是关于避免将 null 作为视图根传递(需要在膨胀布局的根元素上解析布局参数)的主要内容,如果未能解决你的问题,请参考以下文章
无条件布局,来自视图适配器的膨胀:应该使用 View Holder 模式
我可以在不膨胀/重新膨胀布局的情况下将视图添加到滚动视图吗?