不调用嵌套片段的 onCreateView() [英] onCreateView() of nested fragment is not called
问题描述
我一直在浏览 StackOverflow 中的嵌套片段文档、最佳实践和所有可能的链接.我看到了一些建议,以避免在布局文件中使用片段标记,而是通过事务添加它们以实现无缝过渡.
I have been going through nested fragments documentation, best practices and all possible links here in StackOverflow. I have seen suggestions to avoid using fragment tag in layout files and instead add them via transaction for seamless transitions.
在我的应用程序中实现它之前,我尝试了一个简单的例子,我发现了一些意想不到的行为,没有调用 onCreateView() 子片段.我认为,我在理解中遗漏了一些东西,所以我正在寻找一些建议/帮助来解决这个问题.
Before implementing it in my app, I tried a simple example and I found some unexpected behavior, child fragments onCreateView() is not getting called. I assume that , I am missing something in my understanding, so I am looking for some advice/help to sort this out.
示例流程如下:--
MainActivity 托管一个片段(MessageFragment),MessageFragment 托管一个子片段(MessageTextFragment).
MainActivity hosts a fragment(MessageFragment) and the MessageFragment hosts a child fragment(MessageTextFragment).
我使用片段事务以编程方式添加子片段.但是子片段的 onCreateView 永远不会被调用,因此子视图不会膨胀.
I add the child fragment programatically using fragment transaction. But onCreateView of the child fragment never gets called, because of which the sub-view is not inflated.
我正在使用 v4 支持库来处理各处的片段这是我的完整代码:--
I am using v4 support library for fragments everywhere Here is my complete code:--
主活动文件:--
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.root_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = null;
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragment=new MessageFragment().newInstance();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
}
}
MainActivity 的布局文件:-
layout file for MainActivity:-
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/wizard_layout_root"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="vertical">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</RelativeLayout>
第一个Fragment是:MessageFragment--
The first Fragment is: MessageFragment--
public class MessageFragment extends Fragment {
private EditText msgText;
private Activity activity;
TextView tvTitle, tvContent, tvIntro;
Button bAction;
public static MessageFragment newInstance() {
MessageFragment f = new MessageFragment();
return (f);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.message, container, false);
tvTitle = (TextView) view.findViewById(R.id.fragment_title);
tvIntro = (TextView) view.findViewById(R.id.fragment_intro);
tvContent = (TextView) view.findViewById(R.id.fragment_contents);
bAction = (Button) view.findViewById(R.id.fragment_action);
Fragment fragment = getChildFragmentManager().findFragmentById(R.id.sms_message);
if (fragment == null) {
Log.d("MESSAGE_FRAGMENT", "definetly inside");
fragment = MessageEditFragment.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.sms_message, fragment);
transaction.commit();
getChildFragmentManager().executePendingTransactions();
Log.d("MESSAGE_FRAGMENT", "" + getChildFragmentManager().findFragmentById(R.id.sms_message));
}
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = getActivity();
if (activity != null) {
Fragment fragment = getChildFragmentManager().findFragmentById(R.id.sms_message);
Log.d("MESSAGE_FRAGMENT", "onActivityCreated" + fragment);
msgText = (EditText) ((MessageEditFragment)fragment).getView().findViewById(R.id.message_edit_text);
bAction.setEnabled(!msgText.getText().toString().trim().equals(""));
msgText.selectAll();
}
}
}
MessageFragment 的布局(Framelayout 是子片段的容器)
Layout of MessageFragment(Framelayout is the container for child fragment)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/fragment_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/fragment_intro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/fragment_title" />
<LinearLayout
android:id="@+id/ll_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/fragment_intro"
android:layout_weight="1">
<FrameLayout
android:id="@+id/sms_message"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
<Button
android:id="@+id/fragment_action"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_message"/>
</RelativeLayout>
</ScrollView>
</LinearLayout>
这是子片段
public class MessageEditFragment extends Fragment {
private EditText messageEditText;
private MessageLimitWatcher messageLimitWatcher;
private int maxCharacters;
private String messageHeader;
private Button bAction;
public static MessageEditFragment newInstance() {
MessageEditFragment f = new MessageEditFragment();
return(f);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("MESSAGE_FRAGMENT", "onCreateView Of nested fragment");
View view = inflater.inflate(R.layout.message_fragment, container, false);
messageEditText = (EditText) view.findViewById(R.id.message_edit_text);
messageEditText.requestFocus();
return view;
}
及其布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="130dp">
<EditText
android:id="@+id/message_edit_text"
android:layout_height="130dp"
android:layout_width="fill_parent" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"/>
</RelativeLayout>
</LinearLayout>
Logcat 从不打印该行:--
Logcat never prints the line:--
Log.d("MESSAGE_FRAGMENT", "onCreateView 的嵌套片段");
Log.d("MESSAGE_FRAGMENT", "onCreateView Of nested fragment");
当我尝试使用子片段的文本字段时,我得到一个空指针异常,因为它没有被膨胀.所以基本上,我得到空指针:--
and I get a nullpointer exception when I try to use the text field of child fragment, as it is not inflated.So basically, I get nullpointer at:--
((MessageEditFragment)fragment).getView().findViewById(R.id.message_edit_text);
((MessageEditFragment)fragment).getView().findViewById(R.id.message_edit_text);
推荐答案
不要调用 onCreateView
内部的事务,使用 onActivityCteated
或 onCreate代码>.
Don't call the transactions inside of onCreateView
either use onActivityCteated
or onCreate
.
另外值得注意的是不要调用 executePendingTransactions
当你在父片段的 a 中时,这必然会破坏某些东西.
Also worth noting don't call, executePendingTransactions
when you are inside a of the parent fragment, that is bound to break something.
尝试像这样设置你的父片段:
Try to setup your parent fragment something like this:
public class MessageFragment extends Fragment {
private EditText msgText;
private Activity activity;
TextView tvTitle, tvContent, tvIntro;
Button bAction;
public static MessageFragment newInstance() {
MessageFragment f = new MessageFragment();
return (f);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.message, container, false);
tvTitle = (TextView) view.findViewById(R.id.fragment_title);
tvIntro = (TextView) view.findViewById(R.id.fragment_intro);
tvContent = (TextView) view.findViewById(R.id.fragment_contents);
bAction = (Button) view.findViewById(R.id.fragment_action);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = getActivity();
if (activity != null) {
Fragment fragment = getChildFragmentManager().findFragmentById(R.id.sms_message);
Log.d("MESSAGE_FRAGMENT", "onActivityCreated" + fragment);
msgText = (EditText) ((MessageEditFragment)fragment).getView().findViewById(R.id.message_edit_text);
bAction.setEnabled(!msgText.getText().toString().trim().equals(""));
msgText.selectAll();
}
Fragment fragment = MessageEditFragment.newInstance();
getChildFragmentManager().beginTransaction()
.replace(R.id.sms_message, fragment)
.commit();
}
}
这篇关于不调用嵌套片段的 onCreateView()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!