簡體   English   中英

Android:活動和片段之間的通信

[英]Android: Communication between an Activity and a Fragment

我是新手,嘗試邊做邊學,目前Google的搜索結果對我來說太復雜了。

我有一個活動,並成功地通過按按鈕使片段打開和關閉。

public void pressedButton(View v) {
    FragmentActivity fragmentActivity = new FragmentActivity();

    FragmentManager fragmentManager = getSupportFragmentManager();
    android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();

    ft.add(R.id.frame_which_takes_the_fragment, FragmentActivity, "FRAGMENT_TAG");
    ft.commit();

按照片段類的規定,我在Activity中實現了其“ OnFragmentInteractionListener”接口,並覆蓋了onFragmentInteraction方法。

@Override
public void onFragmentInteraction(Uri uri) {

}

現在我不知道該如何進步。 如何從活動向片段發送變量(例如,更新用戶界面中的數字),以及如何向后發送信息?

請記住我是一個流血的初學者,並嘗試使其盡可能簡單和基本。

提前致謝。

那么,您已經在片段中創建了一個接口並在活動中實現了它? 然后,您只需要根據需要創建界面。 onFragmentInteraction(Uri uri)方法只是一個示例,如果您不想將Uri從片段傳遞到活動,則可以刪除該示例。

因此,要傳遞數字,您的界面應如下所示:

interface Listener {
    void onNumberChanged(int number);
}

相關的片段代碼:

listener.onNumberChanged(someNumber);

相關活動代碼:

@Override
public void onNumberChanged(int number) {
    someTextView.setText(Integer.toString(number));
}

隨着ViewModel的發布,您可以使用shared ViewModel在片段和活動之間進行通信。 您只需要在activity范圍內創建ViewModel ,該ViewModel將與activity和所有子fragment共享。

SharedViewModel sharedViewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel::class.java);

然后觀察數據

sharedViewModel.inputNumber.observe(this, observer);  // observer is your observer object

如何從活動向片段發送變量(例如,在用戶界面中更新數字)?

我試圖通過從適配器獲取ListFragment並調用fragment方法來做到這一點,但是卻出現了以下錯誤:

IllegalStateException:無法從分離的片段訪問ViewModels

我的解決方案是改用LocalBroadcastManager:

活動代碼

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
Intent broadcastIntent = new Intent("MAP_SETTINGS_CHANGED");
broadcastIntent.putExtra("NUMBER_TO_SHOW_IN_FRAGMENT", 11);
localBroadcastManager.sendBroadcast(broadcastIntent);

ListFragment /片段代碼

private Context mContext;
private BroadcastReceiver mBroadcastReceiver;

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

    mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, Intent intent) {

            String action = intent.getAction();
            if ("MAP_SETTINGS_CHANGED".equals(action)) {
                int numberToShow = intent.getIntExtra("NUMBER_TO_SHOW_IN_FRAGMENT", -1);
                showNumber(numberToShow);
            }
        }
    };

    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(mContext);
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("MAP_SETTINGS_CHANGED");
    localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);

}

@Override
public void onDetach() {
    super.onDetach();

    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(mContext);
    localBroadcastManager.unregisterReceiver(mBroadcastReceiver);

    mContext = null;
}

同一活動的兩個片段之間有多種通信方式。

  1. 最簡單的方法是使用靜態關鍵字。 在這里,我們可以將要與其他片段共享的方法和變量定義為靜態,並且其他片段可以直接訪問這些變量。 但是這種方法的最大問題是它會導致內存泄漏(靜態定義的COZ)。
  2. 另一種方法是使用Interfaces 在這里,我們在一個片段中使用接口的方法來傳遞值,然后在父活動中實現此接口,並在那里覆蓋該方法,然后使用該方法將值傳遞給子片段。
  3. 另一種最有效的方法是使用ViewModel 我們知道ViewModel會保留到創建它的整個范圍為止。 因此,通常我們使用關鍵字將ViewModel綁定到視圖,就像mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class); 因此,如果我們使用關鍵字,則ViewModel的作用域將一直保留到僅破壞片段為止,一旦破壞了片段,也將清除ViewModel。 因此,如果我們將getActivity()用作ViewModel的范圍,則ViewModel將保留到Activity被銷毀為止。 現在假設您有一個用於A片段的ViewModelA ,並且想要將一些值從A傳遞到B片段,現在您可以做的是,可以將B片段綁定到ViewModelBViewModelA ,因此可以觀察到片段BViewModelA的某些值的變化。

ViewModels方法

片段可以使用其活動范圍共享ViewModel 來處理此通信 ,如以下示例代碼所示:在Google的官方文檔中對此進行了明確說明。 https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}
enter code here

另一個研究此問題的非常好的博客:Android應用程序中Fragment和Activity之間進行通信的8種方法。 https://hackernoon.com/8-ways-to-communicate-between-fragment-and-activity-in-android-apps-235b60005d04

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM