嵌套片段抛出null

时间:2016-02-02 02:01:59

标签: android android-fragments

最终目标是从存储在一个片段中的列表视图中单击, 打开另一个具有嵌套片段视图AnswerFragment的片段, 这里嵌套的片段应该由两个片段组成,顶部是列表中的问题文本,下半部分是答案。现在,我已经成功地将问题文本从列表中传递到单个问题片段(应该存储在答案片段的上半部分)中的通信位。但是它会使单个字段膨胀像SingleQuestionFragment这样的答案片段的问题布局     

   public class MainActivity extends AppCompatActivity implements AllQsFragment.Communicator {

private DrawerLayout mDrawer;
private Toolbar toolbar;

private NavigationView mNVDrawer;
private ActionBarDrawerToggle drawerToggle;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Set a Toolbar to replace the ActionBar.
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = setupDrawerToggle();

    mDrawer.setDrawerListener(drawerToggle);

    //Find our drawer view
    mNVDrawer = (NavigationView) findViewById(R.id.nvView);
    //Setup drawer view
    setupDrawerContent(mNVDrawer);

}

private ActionBarDrawerToggle setupDrawerToggle() {
    return new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.drawer_open, R.string.drawer_close);
}

private void setupDrawerContent(NavigationView navigationView) {
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    selectDrawerItem(menuItem);
                    return true;
                }
            });
}

public void selectDrawerItem(MenuItem menuItem) {
    //Creat a new fragment and specify the planet to show based on
    //position
    Fragment fragment = null;

    Class fragmentClass;
    switch (menuItem.getItemId()) {
        case R.id.nav_first_fragment:
            fragmentClass = AllQsFragment.class;
            break;
        default:
            fragmentClass = AllQsFragment.class;
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    //Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).addToBackStack("addedToBackStack").commit();

    //Highlight the selected item, update the title, and close the drawer
    menuItem.setChecked(true);
    setTitle(menuItem.getTitle());
    mDrawer.closeDrawers();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    //The action bar home/up action should open or close the drawer
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawer.openDrawer(GravityCompat.START);
            return true;
    }

    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    //Sync the toggle state after onRestoreInstanceState has occurred
    drawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //Pass any configuration change to the drawer toggles
}


@Override
public void sendText(String data) {
    SingleQuestionFragment questionFragment = (SingleQuestionFragment) getSupportFragmentManager().findFragmentByTag("fragmentQ");
    if (questionFragment != null) {
        questionFragment.changeText(data);
    } else {
        SingleQuestionFragment fragment = new SingleQuestionFragment();
        Bundle args = new Bundle();
        args.putString("text", data);
        fragment.setArguments(args);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.flContent, fragment)
                .addToBackStack(null).commit();
        fragment.sentText();
    }
}

}

fragment_answer

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.victor.nattest5.AnswerFragment">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/q_fragment">

    </FrameLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/a_fragment">

    </FrameLayout>

</LinearLayout>

AnswerFragment

public class AnswerFragment extends Fragment {

public AnswerFragment() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    insertNestedFragment();
    return inflater.inflate(R.layout.fragment_answer, container, false);

}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
}

private void insertNestedFragment() {
    Fragment childQFragment = new SingleQuestionFragment();
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
    transaction.add(R.id.q_fragment, childQFragment,
                    "fragmentQ").commit();

    Fragment childAFragment = new SingleAnswerFragment();
    FragmentTransaction transaction1 = getChildFragmentManager().beginTransaction();
    transaction1.add(R.id.a_fragment, childAFragment, "fragmentA").commit();
}

public static final AnswerFragment newInstance() {
    AnswerFragment frag = new AnswerFragment();
    return frag;
}
}

SingleQuestionFragment

public class SingleQuestionFragment extends Fragment {
TextView questionTxt;
String stringtext;

public SingleQuestionFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_single_question, container, false);
    questionTxt = (TextView) v.findViewById(R.id.textView_q);
    return v;
}

public static final SingleQuestionFragment newInstance() {
    SingleQuestionFragment frag = new SingleQuestionFragment();
    return frag;
}

public void changeText(String data) {
    questionTxt.setText(data);
}

public void sentText() {
    new BackGroundTask().execute();
}

private class BackGroundTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... strings) {
        Bundle b = getArguments();
        stringtext = b.getString("text");
        return null;
    }

    protected void onPostExecute(String result){
        changeText(stringtext);
    }
}

}

当我使用调试器运行时,应用程序运行时不会崩溃。但是,它显示此行为null - &gt; SingleQuestionFragment questionFragment =(SingleQuestionFragment)getSupportFragmentManager()。findFragmentByTag(&#34; fragmentQ&#34;);

我知道null意味着什么,我只是不明白如何解决这个问题。在我的代码中的某个地方,我想我会夸大额外的布局或者可能会给错误的容器充气。

1 个答案:

答案 0 :(得分:0)

很难提供任何建议,因为您的应用程序很复杂,而且并未发布所有代码。它还不清楚是否有任何已发布的代码包含您尝试解决问题所做的更改。例如,我不了解BackGroundTask的必要性。没有理由在后台线程中执行该处理。你这样做是为了给处理添加一些延迟吗?

您没有发布调用MainActivity.sendText()的代码,或解释导致调用它的原因。

如果我在sendText()中正确理解了您的帖子,则对findFragmentByTag()的调用将返回null,这是一个错误。您是否希望找到SingleQuestionFragment中添加的AnswerFragment?如果是这样,您将无法找到它,因为您只搜索MainActivity管理员持有的片段。搜索不包括子片段管理者持有的片段。换句话说,搜索不会递归搜索片段树。