首页 > 解决方案 > 如何让片段在主活动中显示之前从服务中加载数据?

问题描述

我的 MainActivity 正在加载一个片段(总共有 3 个,由 BottomNavigationBar 控制)。每个片段从LocalBroadcastManager接收数据,这些数据是从AsyncTask发送的(因为它需要执行一些网络任务),它是从NotificationListenerService初始化的(它获取一些音乐信息)。

最初我将所有视图直接加载到 MainActivity 中,它们运行良好,但由于它们是三种不同类型的信息,我决定将它们分成片段。现在,只有正在显示的片段才能获取数据。如果我切换到另一个片段,它不会显示任何内容,直到 NotificationListenerService 再次初始化任务(仅在音乐状态更改时才会发生)。如果我返回显示数据的片段,现在它也不会显示它。

这是我的片段之一的代码(三个片段遵循相同的结构):

String[] lastFmResults;
String[] lastFmKodes;
String[] lastFmDescriptions;

LinearLayout lastFmCards;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_last_fm, container, false);

    lastFmCards = (LinearLayout) view.findViewById(R.id.last_fm_cards);

    LocalBroadcastManager.getInstance(getContext()).registerReceiver(broadcastReceiverLastFm, new IntentFilter("LastFM"));

    return view;
}

private BroadcastReceiver broadcastReceiverLastFm = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        lastFmResults = extras.getStringArray("values");
        lastFmKodes = extras.getStringArray("names");
        lastFmDescriptions = extras.getStringArray("descriptions");

        updateLastFmCards();
    }
};

这是我的主要活动:

ColorsFragment colorsFragment;
LyricsFragment lyricsFragment;
LastFmFragment lastFmFragment;

BottomNavigationView bottomNavigationView;

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

    if (!isNotificationServiceRunning()) {
        startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
    }

    colorsFragment = new ColorsFragment();
    lyricsFragment = new LyricsFragment();
    lastFmFragment = new LastFmFragment();

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(menuItem -> {
        Fragment fragment = null;

        switch (menuItem.getItemId()) {
            case R.id.nav_colors:
                fragment = colorsFragment;
                break;
            case R.id.nav_lyrics:
                fragment = lyricsFragment;
                break;
            case R.id.nav_last_fm:
                fragment = lastFmFragment;
                break;
        }

        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();

        return true;
    });

    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, colorsFragment).commit();
}

我希望片段将加载发送给它们的数据,即使它们尚未显示在 MainActivity 中。

标签: javaandroidandroid-fragments

解决方案


我按照本指南解决了它: https ://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711

它说我必须使用 show() 和 hide() 而不是 replace()。我只需要修改我的 MainActivity:

final ColorsFragment colorsFragment = new ColorsFragment();
final LyricsFragment lyricsFragment = new LyricsFragment();
final LastFmFragment lastFmFragment = new LastFmFragment();

final FragmentManager fragmentManager = getSupportFragmentManager();
Fragment activeFragment = colorsFragment;

BottomNavigationView bottomNavigationView;

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

    if (!isNotificationServiceRunning()) {
        startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
    }

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(menuItem -> {

        switch (menuItem.getItemId()) {
            case R.id.nav_colors:
                fragmentManager.beginTransaction().hide(activeFragment).show(colorsFragment).commit();
                activeFragment = colorsFragment;
                break;
            case R.id.nav_lyrics:
                fragmentManager.beginTransaction().hide(activeFragment).show(lyricsFragment).commit();
                activeFragment = lyricsFragment;
                break;
            case R.id.nav_last_fm:
                fragmentManager.beginTransaction().hide(activeFragment).show(lastFmFragment).commit();
                activeFragment = lastFmFragment;
                break;
        }

        return true;
    });

    fragmentManager.beginTransaction().add(R.id.fragment_container, lastFmFragment, "2").hide(lastFmFragment).commit();
    fragmentManager.beginTransaction().add(R.id.fragment_container, lyricsFragment, "1").hide(lyricsFragment).commit();
    fragmentManager.beginTransaction().add(R.id.fragment_container, colorsFragment, "0").commit();
}

推荐阅读