在呈现之前将数据传递给布局中的片段

时间:2016-11-06 04:46:09

标签: android android-fragments

我需要将数据传递给片段,在渲染之前在活动布局中声明:

<fragment android:name="com.app.fragments.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/myFragment" />

我尝试在Activity的onCreate中执行此操作,但片段已在当时呈现。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Here fragment is already rendered
    mPosts = (MyFragment)getSupportFragmentManager().findFragmentById(R.id.myFragment);
    mPosts.setData(someData);
}

我已经看到了在活动onCreate中以编程方式创建片段而不是添加到容器中的方式。这不是一个非常糟糕的解决方案。但是......有什么比这更简单了吗?

1 个答案:

答案 0 :(得分:1)

对于XML布局,这里有一个问题:https://stackoverflow.com/a/23226281/842607

即使他们不得不说你不能传递参数,但你可以使用回调或自定义属性。

<强>否则

通常,我们以这种方式在参数中使用Bundle

片段类

public class ShopProductListingFragment extends Fragment {

    private static final String TAG = ShopProductListingFragment.class.getSimpleName();

    public static final String KEY_CATEGORY = "category";
    public static final String KEY_URL_PARAMS = "url_params";
    public static final String KEY_URL = "url";

    public static ShopProductListingFragment getInstance(NewCategory category, @NonNull HashMap<String, String> urlParams) {
        Bundle bundle = new Bundle();
        if (null != category)
            bundle.putLong(KEY_CATEGORY, category.getCategory_id());
        bundle.putSerializable(KEY_URL_PARAMS, urlParams);

        ShopProductListingFragment fragment = new ShopProductListingFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    public static ShopProductListingFragment getInstance(@NonNull String url) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(KEY_URL, url);

        ShopProductListingFragment fragment = new ShopProductListingFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    public ShopProductListingFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initVals();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_shop_product_listing, container, false);
        ButterKnife.bind(this, rootView);
        initViews();
        return rootView;
    }

    private void initVals() {
        Bundle bundle = getArguments();

        if (null == bundle || Bundle.EMPTY == bundle)
            throw new NullPointerException("Invalid or null arguments passed to fragment ShopProductListingFragment");

        if (bundle.containsKey(KEY_CATEGORY))
            categoryId = bundle.getLong(KEY_CATEGORY);
        mCategory = StyFi.getInstance().getCategory(categoryId);
        if (bundle.containsKey(KEY_URL_PARAMS))
            urlParams = (HashMap<String, String>) bundle.getSerializable(KEY_URL_PARAMS);
        if (bundle.containsKey(KEY_URL))
            urlFilter = bundle.getString(KEY_URL);
    }

}

Activity

的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

这是在Activity

中实例化的方式
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        if (null == savedInstanceState) {
            ShopProductListingFragment fragment = ShopProductListingFragment.getInstance(category, getUrlParams(data));

            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction().replace(R.id.content_frame, fragment, "SHOP");
            fragmentTransaction.commit();
        }
    }