这个异常的出现往往是因为非法使用了某些方法引起的。
从字面意思上是说这个特定的child已经有一个parent了,你必须在这个parent中首先调用removeView()方法,才能继续你的内容。这里很明显这个child是一个View,一个子(child)View必须依赖于父(parent)View,如果你要使用这个child,则必须通过parent,而你如果就是硬想使用这个child,那么就得让这个child与parent脱离父子关系(即removeView())
何时会出现这种异常呢,典型的是在使用Fragment的时候,在Fragment的onCreateView
中有这样一段代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
LinearLayout drawerListViewContainer = (LinearLayout) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false );
mDrawerListView = (ListView)drawerListViewContainer.findViewById(R.id.drawer_list);
mDrawerListView
.setOnItemClickListener( new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
selectItem(position);
}
});
SimpleAdapter mDrawerAdapter = new SimpleAdapter(getActivity(),getDrawerItems(),R.layout.drawer_item, new String[]{ "img" , "title" }, new int[]{R.id.item_icon,R.id.item_name});
mDrawerListView.setAdapter(mDrawerAdapter);
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true );
return mDrawerListView;
} |
这段代码运行之后即会报出这样的错误
这是因为,返回的mDrawerListView他有一个parent,正确的做法是返回
drawerListViewContainer,其实这也是我的本意,因为大意才写成了返回
mDrawerListView
。
不过仔细想想,为什么就不能返回
mDrawerListView
呢,都是view 没有本质区别啊,这还得看出现这个异常信息的地方发生了什么事,从上面的log中我们知道这个异常产生在ViewGroup的addViewInner方法中。addViewInner的代码如下(部分):
1
2
3
4
5
6
7
8
9
10
11
12
|
private void addViewInner(View child, int index, LayoutParams params,
boolean preventRequestLayout) {
if (mTransition != null ) {
// Don't prevent other add transitions from completing, but cancel remove
// transitions to let them complete the process before we add to the container
mTransition.cancel(LayoutTransition.DISAPPEARING);
}
if (child.getParent() != null ) {
throw new IllegalStateException( "The specified child already has a parent. " +
"You must call removeView() on the child's parent first." );
}
...... |
原来在
中判断了child的parentview 必须为null,否则抛出一个异常。 也就是框架的设计者希望这里必须是一个没有parent的view,如果你不这么做,那么只好给你抛出个异常了,强制这样做也许是为了防止某些问题产生。addViewInner