将数据从活动发送到默认片段的正确方法是什么

时间:2017-03-26 20:42:55

标签: android android-fragments

如何将活动数据发送到默认片段? 我有一个布局文件:

created_at

和java文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.hust.thanhtv.nlp.MainActivity">

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <fragment
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/fragMain"
            class="layout.ListStory">
        </fragment>


    </FrameLayout>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/navigation" />

</LinearLayout>

}

你可以看到将 allStories 发送到片段我必须通过这行代码重新创建 ListChapter 的新实例

private void init(){
    databaseHelper = new DatabaseHelper(this);
    allStories = databaseHelper.getListStory();
    FragmentManager fm = getSupportFragmentManager();
    Fragment  frchapter = ListChapter.newInstance(allStories);
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.replace(R.id.fragMain, frchapter);
    transaction.commit();
}

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                return true;
            case R.id.navigation_dashboard:
                return true;
            case R.id.navigation_notifications:
                return true;
        }
        return false;
    }

};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    init();
}

(我打电话给

时创建了旧实例
Fragment  frchapter = ListChapter.newInstance(allStories);

对吗?)然后我用这个块替换这个新的实例:

setContentView(R.layout.activity_main);

我认为没有必要重新创建ListChapter实例来完成这项工作我不知道是否有其他方法可以做到这一点(我的意思是我想直接将数据发送到旧实例并在那里更新一些元素)。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

我会使用Parceble接口在片段和活动之间发送数据。我还使用共享首选项来链接这些组件之间的数据。您可以根据自己的喜好操作LocalBroadcastManager来广播和收听事件。

一个能够有效地完成前述工作的优秀图书馆,是EventBus。

这些Parceble和bundle方法的主要问题之一是它们可以在每个组件之间创建强大的依赖关系,这使得很难在不影响其他区域的情况下更改系统的某个部分。

发布/订阅模型试图通过依赖事件总线模型来避免这种紧密集成。在这种类型的模型中,有发布者和订阅者。发布者负责发布事件以响应某种类型的状态更改,而订阅者则会响应这些事件。

该事件充当交换信息,隔离和最小化每一方之间依赖关系的中介。通过这种方式,消息总线可以创建一个通信管道,旨在帮助您的应用程序更易于维护和扩展。

Android优化事件总线,简化了活动,碎片,线程,服务等之间的通信。减少代码,提高质量。 Link.

要清除您的初始问题,您希望将数据传递给片段而不必每次都重新创建(在主布局中替换),您有选项,最简单的方法是创建一个设置文件内容的公共静态方法,从而提供任何类访问为片段提供和访问数据。或者就像我之前说的那样,您可以创建一个Shred首选项并将其视为一个中央数据存储池,以及任何请求访问的类。或者,如果您确实阅读了有关事件总线的信息,则可以将初始类视为发送数据的发布者(例如,开始片段),然后将订阅者(您的片段)视为侦听和捕获数据。这种方式更清晰,因为任何这样的组件之间没有严格的依赖关系。还是不相信?