Данные не загружаются в HomeFragment после использования другого меню в BottomNavigationView в Android - PullRequest
0 голосов
/ 11 апреля 2020

Я получаю данные из сети и показываю в моем списке. Я использую BottomNavigationView на главном экране. Показывает 4 вкладки. Когда я запускаю приложение, данные загружаются на главном экране, но когда я go перехожу на какую-либо другую вкладку в виде навигации снизу и возвращаюсь на главную страницу, данные не загружаются. На главном экране есть вкладки просмотра пейджеров.

MainActivity.kt

class MainActivity: 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: Fragment () {tabinayit var tabs: TabLayout lateinit var pager: 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) {
    }
}

}

фрагмент_основ. 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>

Главный экран

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
    }
}

1 Ответ

1 голос
/ 11 апреля 2020

Вам необходимо добавить

pager.setOffscreenPageLimit(2)

После

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

Подробнее https://developer.android.com/reference/android/support/v4/view/ViewPager#setoffscreenpagelimit

ОБНОВЛЕНИЕ

В соответствии с новыми находками, когда вы проводите между фрагментами, ваше состояние фрагмента сохраняется. Оно сохраняется, потому что, когда вы проводите, Viewpager вступает в действие. И когда вы устанавливаете pager.setOffscreenPageLimit (2), сохраняются 2 фрагмента с обеих сторон. Но у вас нет проблем со смахиванием.

Но когда вы выбираете фрагмент с помощью BottomNavigationView, вы используете замену. Метод replace удаляет фрагмент из контейнера, поэтому onCreate() будет выполняться каждый раз, когда пользователь переключает вкладки.

Используя следующий код для BottomNavigationView, вы можете решить эту проблему.

Итог : Вместо создания / замены новых фрагментов с BottomNavigationView вы можете использовать скрытие.

MainActivity

Объявить переменную фрагмента следующим образом:

Fragment activeFragment= new MainFragment();

В onCreate, после setContentView, скрыть все фрагменты и зафиксировать их в диспетчере фрагментов, но не скрывать первый фрагмент, который будет обслуживать как домашний фрагмент.

  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;
}

2-е ОБНОВЛЕНИЕ

Замените

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

С

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