onCreateView() of nested fragment is not called

穿精又带淫゛_ 提交于 2019-11-26 23:33:51

问题


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.

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.

The example flow is as below:--

MainActivity hosts a fragment(MessageFragment) and the MessageFragment hosts a child fragment(MessageTextFragment).

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.

I am using v4 support library for fragments everywhere Here is my complete code:--

MainActivity file:--

 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();
            }
        }
}

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>

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();
        }
    }
}

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>

This is the child fragment

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;
    }

and its layout

<?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 never prints the line:--

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);


回答1:


Don't call the transactions inside of onCreateView either use onActivityCteated or onCreate.

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();
  }
}



回答2:


Maybe you should not add child fragment(say call transaction.add within a fragment).

Do fragment transaction only on Activity.

When you want to do fragment transaction, you could notify the Activity hosting the current fragment, through EventBus, or an interface implemented by the host Activity.



来源:https://stackoverflow.com/questions/32240138/oncreateview-of-nested-fragment-is-not-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!