使用FragmentTransaction问题更新容器内动态分配的片段

时间:2016-04-10 01:19:02

标签: android android-fragments

我正在使用Multipane应用,其中最左边的窗格是静态的,右窗格有动态添加的片段。

这是布局:

<?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:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<fragment
    android:name="path.fragments.NavigationFragment"
    android:id="@+id/navigation_fragment"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="match_parent"
    tools:layout="@layout/navigation_layout" />

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="0dp"
    android:layout_weight="2"
    android:layout_height="match_parent" />


</LinearLayout>

每当在左窗格中选择一个包含用户列表的列表项时,我想创建一个新片段并将其添加到容器中,并用该用户的消息填充它。我的其余逻辑工作得很好,但我只是在动态添加新片段时遇到问题。在使用FragmentTransaction替换它之前更新现有片段。但是,当我尝试下面的代码时,它不起作用

    DetailsFragment detailsFragment = new DetailsFragment();
    Bundle args = new Bundle();
    args.putInt(DetailsFragment.ARG_POSITION, position);
    detailsFragment.setArguments(args);
    FragmentTransaction trans = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    trans.replace(R.id.fragment_container, detailsFragment);
    trans.addToBackStack(null);
    trans.commit();


    Log.v(TAG, "updating details fragment with argument = " + position);

    Cursor cursor = (Cursor) adapter.getItem(position);
    Peer peer = new Peer(cursor);

    String[] from = new String[] {MessageContract.TEXT};
    int[] to = new int[] {android.R.id.text1};
    adapter2 = new SimpleCursorAdapter(
            this,
            android.R.layout.simple_expandable_list_item_1,
            null,
            from,
            to, 2);

    detailsFragment = (DetailsFragment)
            getSupportFragmentManager().findFragmentById(R.id.fragment_container);

    ListView LV = (ListView) detailsFragment.getView().findViewById(android.R.id.list);
    LV.setAdapter(adapter2);

总之,我想做的是:

  • 创建新片段
  • 将其添加到容器
  • 并从MainActivity更新视图

此外,在MainActivity中的onCreate中我有:

    if (findViewById(R.id.fragment_container) != null) {

        // However, if we're being restored from a previous state,
        // then we don't need to do anything and should return or else
        // we could end up with overlapping fragments.
        if (savedInstanceState != null) {
            return;
        }

        // Create a new Fragment to be placed in the activity layout
        DetailsFragment firstFragment = new DetailsFragment();

        // In case this activity was started with special instructions from an
        // Intent, pass the Intent's extras to the fragment as arguments
        firstFragment.setArguments(getIntent().getExtras());

        // Add the fragment to the 'fragment_container' FrameLayout
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, firstFragment).commit();
    }

如果我不够清楚,请接受我的道歉,并提前感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

来自Fragments Developer Guide

&#34;调用commit()不会立即执行事务。相反,它会安排它在活动的UI线程(&#34;主要&#34;线程)上运行,一旦线程能够这样做。&#34;

在提交FragmentTransaction后,您几乎可以立即获得以下代码行。

ListView LV = (ListView) detailsFragment.getView().findViewById(android.R.id.list);
LV.setAdapter(adapter2);

View detailsFragment很可能尚未创建。{ 看看Complete Activity/Fragment Lifecycle。在Fragment附加Activity之后才会进行视图创建。

如果您需要将adapter2Activity传递到Fragment,您可以在Fragment中创建成员变量和设置器,但不要在ListView上设置适配器,直到创建Fragment's View为止。

例如,在Fragment

// member variable to hold the adapter
private SimpleCursorAdapter mAdapter2;

// setter for the member variable
private void setAdapter2(SimpleCursorAdapter adapter) {
    mAdapter2 = adapter;
}

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

    // Now that the view is created, we can set the adapter.
    ListView LV = (ListView) view.findViewById(android.R.id.list);
    LV.setAdapter(mAdapter2);
}

在您的Activity

// Create the new Fragment
DetailsFragment detailsFragment = new DetailsFragment();

// Add the Arguments to the Fragment
Bundle args = new Bundle();
args.putInt(DetailsFragment.ARG_POSITION, position);
detailsFragment.setArguments(args);

// Create the adapter
Cursor cursor = (Cursor) adapter.getItem(position);
Peer peer = new Peer(cursor);

String[] from = new String[] {MessageContract.TEXT};
int[] to = new int[] {android.R.id.text1};
adapter2 = new SimpleCursorAdapter(
        this,
        android.R.layout.simple_expandable_list_item_1,
        null,
        from,
        to, 2);

// Set the Adapter for the Fragment
detailsFragment.setAdapter2(adapter2);

// Do the FragmentTransaction
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.fragment_container, detailsFragment);
trans.addToBackStack(null);
trans.commit();