我一直在浏览StackOverflow中的嵌套片段文档,最佳实践和所有可能的链接。我已经看到了避免在布局文件中使用片段标记的建议,而是通过事务添加它们以实现无缝转换。
在我的应用程序中实现它之前,我尝试了一个简单的例子,我发现了一些意想不到的行为,没有调用onCreateView()的子片段。 我认为,我在理解中遗漏了一些东西,所以我正在寻找一些建议/帮助来解决这个问题。
示例流程如下: -
MainActivity托管一个片段(MessageFragment),MessageFragment托管一个子片段(MessageTextFragment)。
我使用片段事务以编程方式添加子片段。 但永远不会调用子片段的onCreateView,因为子视图不会被夸大。
我正在使用 v4支持库来处理所有片段 这是我的完整代码: -
MainActivity文件: -
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的布局文件: -
<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>
第一个片段是: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是子片段的容器)
<?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从不打印该行: -
Log.d(“MESSAGE_FRAGMENT”,“onCreateView Of nested fragment”);
当我尝试使用子片段的文本字段时,我得到一个nullpointer异常,因为它没有膨胀。所以基本上,我得到nullpointer: -
((MessageEditFragment)片段).getView()findViewById(R.id.message_edit_text);
答案 0 :(得分:0)
请勿使用 if(savedInstanceState!=null){
Fragment fragment = getSupportFragmentManager().getFragment(savedInstanceState,"fragmentInstanceSaved");
//recreate your preserved fragment here
}else{
//goto ur default activity or fragment....
}
或onCreateView
调用onActivityCteated
内的交易。
另外值得注意的是,当您在父片段中时,不要调用onCreate
,这必然会破坏某些内容。
尝试设置这样的父片段:
executePendingTransactions
答案 1 :(得分:-2)
也许你不应该添加子片段(比如在片段中调用transaction.add
)。
仅对Activity进行片段交易。
如果要进行片段事务处理,可以通过EventBus或主机Activity实现的接口通知托管当前片段的Activity。