片段视图上的getParent()旋转后在onresume()中返回null
我在onresume()
中具有以下代码,该自定义片段扩展了list fragment
,它试图找到其父:
@Override
public void onResume() {
super.onResume();
System.out.println("resume");
View view = getView();
System.out.println("view is " + (view != null ? "not " : "" ) + "null");
ViewParent parent = view != null ? view.getParent() : null;
System.out.println("parent is " + (parent != null ? "not " : "" ) + "null");
if(view != null) {
System.out.println(view.getRootView());
}
}
当我最初在模拟器中运行该应用程序时,它会打印出来:
I/System.out: resume
I/System.out: view is not null
I/System.out: parent is not null
I/System.out: com.android.internal.policy.impl.PhoneWindow$DecorView{ ... }
但是,在旋转模拟器后,它打印出来:
I/System.out: resume
I/System.out: view is not null
I/System.out: parent is null
I/System.out: android.widget.FrameLayout{ ... }
即使在应用程序中可见片段,它看起来似乎还没有正确连接到视图树中的视图> on resume() ,由于root视图是framelayout
,它是片段的根视图,而不是应用程序的根视图。
可能是什么原因?我如何在/之后 onresume() in/eward of line for line line getActivity()。 someid)
?
编辑:
当我在onresume()
中调整代码时,以在下一个帧中打印根视图(使用view.post()
),它 do 找到正确的根视图(这意味着我可以访问父):
@Override
public void onResume() {
super.onResume();
System.out.println("resume");
View view = getView();
System.out.println("view is " + (view != null ? "not " : "" ) + "null");
ViewParent parent = view != null ? view.getParent() : null;
System.out.println("parent is " + (parent != null ? "not " : "" ) + "null");
if(view != null) {
System.out.println(view.getRootView());
/**
* added to see if it finds the proper root view in the next frame
*/
view.post(() -> {
System.out.println("how about after post?");
System.out.println(view.getRootView());
});
}
}
现在打印:
I/System.out: view is not null
I/System.out: parent is null
I/System.out: android.widget.FrameLayout{ ... }
I/System.out: how about after post?
I/System.out: com.android.internal.policy.impl.PhoneWindow$DecorView{ ... }
但是使用view.post()
就像那样,就像一个令人讨厌的hack 。
编辑:
因此,看来操作顺序不是我预期的(可能是一个错误?)。
但是我可能找到了一个解决方案,如果它按预期工作,我将作为答案发布。这个想法是在onviewCreated()
中添加view.onattachstataChstataChstataChStataChstataChstataChstataChStateChangeNeSener
,从而在view.onattachstataChstataChstataChstataChstataChstataChStateChangElistener.OnviewAttAchedTowAttOWATTOWINDOW()中找到parent >而不是
fragment.onresume()
。
I have the following code in onResume()
in a custom fragment that extends ListFragment
, which tries to find its parent:
@Override
public void onResume() {
super.onResume();
System.out.println("resume");
View view = getView();
System.out.println("view is " + (view != null ? "not " : "" ) + "null");
ViewParent parent = view != null ? view.getParent() : null;
System.out.println("parent is " + (parent != null ? "not " : "" ) + "null");
if(view != null) {
System.out.println(view.getRootView());
}
}
When I run the app initially in the emulator it prints:
I/System.out: resume
I/System.out: view is not null
I/System.out: parent is not null
I/System.out: com.android.internal.policy.impl.PhoneWindow$DecorView{ ... }
However, after rotating the emulator, it prints:
I/System.out: resume
I/System.out: view is not null
I/System.out: parent is null
I/System.out: android.widget.FrameLayout{ ... }
Even though the fragment is visible just fine in the app, it appears as though it's view is not properly attached into the view tree yet in onResume()
after rotating, since the root view is the FrameLayout
which is the root view of the fragment and not the root view of the app.
What could be the cause of this and how can I properly access its ViewParent
in/after onResume()
, without resorting to something line getActivity().findViewById(someId)
?
edit:
When I adjust the code in onResume()
to print the root view in the next frame (using View.post()
), it does find the proper root view (which means I can access the parent):
@Override
public void onResume() {
super.onResume();
System.out.println("resume");
View view = getView();
System.out.println("view is " + (view != null ? "not " : "" ) + "null");
ViewParent parent = view != null ? view.getParent() : null;
System.out.println("parent is " + (parent != null ? "not " : "" ) + "null");
if(view != null) {
System.out.println(view.getRootView());
/**
* added to see if it finds the proper root view in the next frame
*/
view.post(() -> {
System.out.println("how about after post?");
System.out.println(view.getRootView());
});
}
}
Now it prints:
I/System.out: view is not null
I/System.out: parent is null
I/System.out: android.widget.FrameLayout{ ... }
I/System.out: how about after post?
I/System.out: com.android.internal.policy.impl.PhoneWindow$DecorView{ ... }
But utilizing View.post()
like that just feels like a nasty hack.
edit:
So, it appears the order of operations is not as I would have expected (might be a bug?).
But I may have found a solution, which I will post as an answer if it works as intended. The idea is to add a View.OnAttachStateChangeListener
to the fragment view in onViewCreated()
and thus find the parent in View.OnAttachStateChangeListener.onViewAttachedToWindow()
instead of in Fragment.onResume()
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经通过将我的逻辑从
onResume()
转移到view.onattachstatatechangelistener
中,通过将我的逻辑从onResume()
移动到解决问题来解决问题。现在,它的行为按照我的意图。
外卖是
onResume()
不是一个可靠的方法,在其中假设片段视图已经连接到视图树。I've managed to solve the issue by moving my logic from
onResume()
into anView.OnAttachStateChangeListener
that I add inonViewCreated()
:Now it behaves as I intended.
The take-away is that
onResume()
is not a reliable method in which to assume the fragment view is attached to the view tree already.