在 Android 的 BottomNavigationView 中使用不同的菜单后,数据未加载到 HomeFragment 中

Data is not loading in HomeFragment after using different menu in BottomNavigationView in Android

我正在从网络获取数据并显示在我的列表中。我在主屏幕中使用 BottomNavigationView。它显示 4 个选项卡。当我启动该应用程序时,数据正在主屏幕中加载,但是当我转到底部导航视图中的其他选项卡并返回到主页选项卡时,数据未加载。在主屏幕中有查看分页器选项卡。

MainActivity.kt

class 主活动:AppCompatActivity(),BottomNavigationView.OnNavigationItemSelectedListener {

lateinit var tabs: TabLayout
lateinit var toolbar: Toolbar
lateinit var sharedPreferences: SharedPreferences

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    sharedPreferences = getSharedPreferences(AppConstants.PREF_NAME, Context.MODE_PRIVATE)

    toolbar = findViewById(R.id.toolbar)
    setSupportActionBar(toolbar)
    toolbar.setTitle(R.string.app_name)

    val navigationView1: BottomNavigationView = findViewById(R.id.nav_view)
    navigationView1.setOnNavigationItemSelectedListener(this)

    if (savedInstanceState == null) {
        loadFragment(MainFragment())
    }
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    var fragment: Fragment? = null

    when (item.itemId) {
        R.id.news -> {
            invalidateOptionsMenu()
            fragment = MainFragment()
        }

        R.id.source -> {
            fragment = SourcesFragment()
            toolbar.getMenu().clear()
            toolbar.setTitle("News Sources")
        }

        R.id.save -> {
            toolbar.setTitle("Saved Articles")
            toolbar.getMenu().clear()
            fragment = WatchListFragment()
        }

        R.id.settings -> {
            toolbar.setTitle("Settings")
            toolbar.getMenu().clear()
            fragment = SettingsFragment()
        }
    }

    loadFragment(fragment)
    return true
}

private fun loadFragment(fragment: Fragment?) {
    val transaction = supportFragmentManager.beginTransaction()
        .setCustomAnimations(R.anim.design_bottom_sheet_slide_in, R.anim.design_bottom_sheet_slide_out)
    transaction.replace(R.id.container, fragment!!)
    transaction.commit()
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    when (item?.itemId) {
        R.id.action_search -> {
            startActivity(Intent(this, SearchActivity::class.java))
        }
        else -> ""
    }
    return true
}

}

MainFragment.kt

class MainFragment:片段(){ lateinit var 选项卡:TabLayout lateinit var 寻呼机:ViewPager lateinit var 适配器:PagerAdapter

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    var view = inflater.inflate(R.layout.fragment_main, container, false)

    pager = view.findViewById(R.id.viewpager)
    setupViewPager(pager)

    pager.addOnPageChangeListener(onPageChangeListener)

    tabs = view.findViewById(R.id.tabs)
    tabs.setupWithViewPager(pager)
    Log.d("LIVE", "onCreateView")
    return view
}

private fun setupViewPager(pager: ViewPager) {
    adapter = PagerAdapter(fragmentManager!!)
    adapter.addFragment(TopNewsFragment(), "Top News")
    adapter.addFragment(TechnologyFragment(), "Technology")
    adapter.addFragment(BusinessFragment(), "Business")
    adapter.addFragment(SportsFragment(), "Sports")
    adapter.addFragment(EntertainmentFragment(), "Entertainment")
    adapter.addFragment(ScienceFragment(), "Science")
    adapter.addFragment(HealthFragment(), "Health")
    pager.adapter = adapter
    adapter.notifyDataSetChanged()
}
private val onPageChangeListener = object : ViewPager.OnPageChangeListener {
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    }

    override fun onPageSelected(position: Int) {
        adapter.notifyDataSetChanged()
    }

    override fun onPageScrollStateChanged(state: Int) {
    }
}

}

fragment_main.xml

<FrameLayout 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:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            style="@style/Widget.MaterialComponents.TabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:elevation="10dp"
            app:tabGravity="center"
            app:tabIndicatorColor="@color/tab_selected_color"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="@color/tab_selected_color"
            app:tabTextColor="@color/textColorPrimary" />

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </LinearLayout>

</FrameLayout>

activity_main.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:elevation="10dp">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:elevation="4dp"
        app:itemIconTint="@drawable/bottom_navigation_text_color"
        app:itemTextColor="@drawable/bottom_navigation_text_color"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/bottom_navigation_menu" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Home Screen

DataNotloading

更新代码:

class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

    lateinit var tabs: TabLayout
    lateinit var toolbar: Toolbar
    lateinit var sharedPreferences: SharedPreferences

    private val mNewsFragment = MainFragment()
    private val mSourceFragment: SourcesFragment = SourcesFragment()
    private val mSaveFragment: WatchListFragment = WatchListFragment()
    private val mSettingFragment = SettingsFragment()

    var activeFragment: Fragment= MainFragment()
    val fm: FragmentManager = supportFragmentManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sharedPreferences = getSharedPreferences(AppConstants.PREF_NAME, Context.MODE_PRIVATE)

        toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)
        toolbar.setTitle(R.string.app_name)

        val navigationView1: BottomNavigationView = findViewById(R.id.nav_view)
        navigationView1.setOnNavigationItemSelectedListener(this)

        fm.beginTransaction().add(R.id.container, activeFragment).commit();
        fm.beginTransaction().add(R.id.container, mSettingFragment).hide(mSettingFragment).commit();
        fm.beginTransaction().add(R.id.container, mSourceFragment).hide(mSourceFragment).commit();
        fm.beginTransaction().add(R.id.container, mSaveFragment).hide(mSaveFragment).commit();

/*        if (savedInstanceState == null) {
            val transaction = supportFragmentManager.beginTransaction()
                .setCustomAnimations(R.anim.design_bottom_sheet_slide_in, R.anim.design_bottom_sheet_slide_out)
            transaction.add(R.id.container, activeFragment).commit();
            transaction.add(R.id.container, activeFragment).hide(activeFragment).commit();
            transaction.add(R.id.container, activeFragment).hide(activeFragment).commit();
        }*/
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        var fragment: Fragment? = null

        when (item.itemId) {
            R.id.news -> {
                invalidateOptionsMenu()
                fragment = MainFragment()
                toolbar.getMenu().clear()
                toolbar.setTitle("News Headlines")
            }

            R.id.source -> {
                fragment = SourcesFragment()
                toolbar.getMenu().clear()
                toolbar.setTitle("News Sources")
            }

            R.id.save -> {
                toolbar.setTitle("Saved Articles")
                toolbar.getMenu().clear()
                fragment = WatchListFragment()
            }

            R.id.settings -> {
                toolbar.setTitle("Settings")
                toolbar.getMenu().clear()
                fragment = SettingsFragment()
            }
        }

        loadFragment(fragment)
        return true
    }

    private fun loadFragment(fragment: Fragment?) {
        val transaction = supportFragmentManager.beginTransaction()
            .setCustomAnimations(R.anim.design_bottom_sheet_slide_in, R.anim.design_bottom_sheet_slide_out).hide(activeFragment).show(fragment!!).commit();
        activeFragment = fragment;
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            R.id.action_search -> {
                startActivity(Intent(this, SearchActivity::class.java))
            }
            else -> ""
        }
        return true
    }
}

您需要添加

pager.setOffscreenPageLimit(2)

之后

pager = view.findViewById(R.id.viewpager)

详情 https://developer.android.com/reference/android/support/v4/view/ViewPager#setoffscreenpagelimit

更新

根据新发现,当您在片段之间滑动时,您的片段状态是 saved.It 已保存,因为当您滑动时,Viewpager 开始运行。当你设置 pager.setOffscreenPageLimit(2) 时,两边的 2 个片段是 saved.Hence 你滑动没有问题。

但是当您使用 BottomNavigationView 选择片段时,您正在使用替换。 replace 方法从容器中删除片段,因此每次用户切换选项卡时都会执行 onCreate()

对BottomNavigationView使用下面的代码,就可以解决这个问题。

底线而不是 Creating/replacing 带有 BottomNavigationView 的新片段,您可以使用隐藏。

MainActivity

像那样声明片段变量

Fragment activeFragment= new MainFragment();

在onCreate中,setContentView后,隐藏所有的fragment,提交给fragment manager,但不隐藏第一个作为home fragment的fragment。

  fm.beginTransaction().add(R.id.main_container,fragment1).commit();
  fm.beginTransaction().add(R.id.main_container, fragment2).hide(fragment2).commit();
  fm.beginTransaction().add(R.id.main_container, fragment3).hide(fragment3).commit();

像那样替换你的 loadFragment()。

 private fun loadFragment(fragment: Fragment?) {
    val transaction = supportFragmentManager.beginTransaction()
        .setCustomAnimations(R.anim.design_bottom_sheet_slide_in, R.anim.design_bottom_sheet_slide_out).hide(activeFragment).show(fragment).commit();
    transaction.commit()
       activeFragment=fragment;
}

第二次更新

替换

  fm.beginTransaction().add(R.id.main_container,fragment1).commit();

  fm.beginTransaction().add(R.id.main_container,activeFragment).commit();