嵌套片段onCreateView()不叫 [英] onCreateView() of nested fragment is not called

查看:141
本文介绍了嵌套片段onCreateView()不叫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在经历嵌套的片段文件,最佳实践和一切可能的环节在这里计算器。我所看到的建议,以避免使用片段标签在布局文件,而是通过交易增加他们的无缝转移。

在我的应用程序执行前,我想一个简单的例子,我发现了一些意外的行为,孩子的片段onCreateView()是没有得到调用。 我认为,我失去了一些东西在我的理解,所以我找了一些意见/帮助整理了这一点。

这个例子流程如下: -

MainActivity举办片段(MessageFragment)和MessageFragment承载了孩子片段(MessageTextFragment)。

我添加子片段编程方式使用片段交易。 但子片段的onCreateView从未被调用,这是因为副视野不膨胀。

我使用的 V4支持库的碎片随处可见 这是我的完整的code: -

MainActivity文件: -

 公共类MainActivity扩展AppCompatActivity {
        @覆盖
        保护无效的onCreate(包savedInstanceState){
            super.onCreate(savedInstanceState);
            的setContentView(R.layout.root_layout);
            FragmentManager fragmentManager = getSupportFragmentManager();
            片段片段= NULL;
            如果(savedInstanceState == NULL){
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                片段=新MessageFragment()的newInstance()。
                fragmentTransaction.add(R.id.fragment_container,片段);
                fragmentTransaction.commit();
            }
        }
}
 

有关MainActivity布局文件: -

 < RelativeLayout的
        的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:ID =@ + ID / wizard_layout_root
        机器人:以下属性来=5DP
        机器人:paddingRight =5DP
        机器人:方向=垂直>
    <的FrameLayout
        机器人:ID =@ + ID / fragment_container
        机器人:layout_height =FILL_PARENT
        机器人:layout_width =FILL_PARENT/>
< / RelativeLayout的>
 

第一个片段是:MessageFragment -

 公共类MessageFragment扩展片段{
    私人的EditText MSGTEXT;

    私人活动的活动;

    TextView的tvTitle,tvContent,tvIntro;
    按钮bAction;

    公共静态MessageFragment的newInstance(){
        MessageFragment F =新MessageFragment();
        返程(F);
    }

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){
        查看查看= inflater.inflate(R.layout.message,集装箱,假);
        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 =(按钮)view.findViewById(R.id.fragment_action);

        片段片段= getChildFragmentManager()findFragmentById(R.id.sms_message)。
        如果(片段== NULL){
            Log.d(MESSAGE_FRAGMENT,definetly内部);
            片段= MessageEditFragment.newInstance();
            FragmentTransaction交易= getChildFragmentManager()的BeginTransaction()。
            transaction.add(R.id.sms_message,片段);
            器transaction.commit();
            getChildFragmentManager()executePendingTransactions()。
            Log.d(MESSAGE_FRAGMENT,+ getChildFragmentManager()findFragmentById(R.id.sms_message));
        }
        返回查看;
    }

    @覆盖
    公共无效onActivityCreated(包savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        活性= getActivity();
        如果(活动!= NULL){
            片段片段= getChildFragmentManager()findFragmentById(R.id.sms_message)。
            Log.d(MESSAGE_FRAGMENT,onActivityCreated+片段);
            MSGTEXT =(EditText上)((MessageEditFragment)片段).getView()findViewById(R.id.message_edit_text)。
            bAction.setEnabled(!。msgText.getText()的toString()修剪()等于());
            msgText.selectAll();
        }
    }
}
 

MessageFragment的布局(的FrameLayout是容器的子片段)

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:descendantFocusability =beforeDescendants
    机器人:focusableInTouchMode =真
    机器人:方向=垂直>
    <滚动型
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT>
        < RelativeLayout的
            机器人:layout_width =FILL_PARENT
            机器人:layout_height =WRAP_CONTENT>

            <的TextView
                机器人:ID =@ + ID / fragment_title
                机器人:layout_width =WRAP_CONTENT
                机器人:layout_height =WRAP_CONTENT
                机器人:layout_centerHorizo​​ntal =真/>

            <的TextView
                机器人:ID =@ + ID / fragment_intro
                机器人:layout_width =WRAP_CONTENT
                机器人:layout_height =WRAP_CONTENT
                机器人:layout_below =@ + ID / fragment_title/>

            <的LinearLayout
                机器人:ID =@ + ID / ll_message
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT
                机器人:layout_below =@ + ID / fragment_intro
                机器人:layout_weight =1>
                <的FrameLayout
                    机器人:ID =@ + ID / sms_message
                    机器人:layout_width =FILL_PARENT
                    机器人:layout_height =FILL_PARENT/>
            < / LinearLayout中>
            <按钮
                机器人:ID =@ + ID / fragment_action
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT
                机器人:layout_below =@ + ID / ll_message/>
        < / RelativeLayout的>
    < /滚动型>
< / LinearLayout中>
 

这是孩子片段

 公共类MessageEditFragment扩展片段{

    私人的EditText messageEditText;

    私人MessageLimitWatcher messageLimitWatcher;
    私人诠释maxCharacters;
    私人字符串的MessageHeader;
    私人按钮bAction;

    公共静态MessageEditFragment的newInstance(){
        MessageEditFragment F =新MessageEditFragment();
        返程(F);
    }

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){
        Log.d(MESSAGE_FRAGMENT,onCreateView嵌套的片段);
        查看查看= inflater.inflate(R.layout.message_fragment,集装箱,假);
        messageEditText =(EditText上)view.findViewById(R.id.message_edit_text);
        messageEditText.requestFocus();
        返回查看;
    }
 

和它的布局

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_width =FILL_PARENT>
    < RelativeLayout的
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =130dp>
        <的EditText
            机器人:ID =@ + ID / message_edit_text
            机器人:layout_height =130dp
            机器人:layout_width =FILL_PARENT/>
        <的TextView
            机器人:layout_width =FILL_PARENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字颜色=@机器人:彩色/黑白/>
    < / RelativeLayout的>
< / LinearLayout中>
 

的logcat从来没有打印该行: -

  

Log.d(MESSAGE_FRAGMENT,onCreateView嵌套的片段);

当我尝试使用子片段的文本字段我得到一个空指针异常,因为它不是inflated.So基本上,我得到空指针是: -

  

((MessageEditFragment)片段).getView()findViewById(R.id.message_edit_text);

解决方案

也许你不应该添加子片段(比如呼叫 transaction.add 片段内)。

执行片段交易只在活动。

当你想要做的交易片段,您可以通知活动主办当前片段,通过EventBus,或由主机活动实现的接口。

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

解决方案

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.

这篇关于嵌套片段onCreateView()不叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆