Обновить / Обновить фрагмент с новыми данными, полученными в результате действий с TabLayout и FragmentPagerAdapter

android android-layout android-fragments

2780 просмотра

3 ответа

56 Репутация автора

Мое приложение состоит из ActivityHome с использованием TabLayoutи SectionsPagerAdapter extends FragmentPagerAdapterдля вставки заполнителя в два внутренних фрагмента (FragmentLeft и FragmentRight).

ActivityHome загружает данные из базы данных и передает их через связку в два фрагмента, используя метод getItem из SectionsPagerAdapter (в значительной степени базовый SectionsPagerAdapter)

FragmentRight создает всплывающее окно, которое содержит в себе еще один фрагмент (FragmentPopup). Этот фрагмент дает пользователю возможность вносить изменения и сохранять все в базу данных с помощью запроса UPDATE.

Эти данные отображаются в FragmentLeft и FragmentRight, я хотел бы обновить их, когда база данных обновляется через FragmentPopup.

Для этого я определил интерфейс в FragmentPopup ( interfaceDataFragmentPopUpToActivity), этот интерфейс реализован в HomeActivity. Через этот интерфейс ActivityHome видит, что данные были изменены, и обновляет данные, которые затем будут переданы в двух фрагментах. Это обновление данных выполняется в ActivityHome с реализацией метода моего интерфейса. Кроме того, я переписал notifyDataSetChanged()метод моего класса SectionsPagerAdapter, чтобы попытаться обновить два фрагмента. Проблема в том, что я не могу перезарядить фрагменты (меня интересует прежде всего FragmentLeft) должным образом.

Это небольшая часть кода MainActivity

public class ActivityHome extends AppCompatActivity InterfaceDataFragmentPopUpToActivity {

    private SectionsPagerAdapter mSectionsPagerAdapter;
    private ViewPager mViewPager;
    private Bundle bundle;
    private FragmentLeft fragmentLeft;
    private FragmentRight fragmentRight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ...

        // Set up the ViewPager with the sections adapter.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        ...
    }

    //method from my interface
    @Override
    public void updateData(Boolean changeData) {
        if (changeData) {

            ...
            Load data from database;
            ...

            bundle = new Bundle();
            bundle.putParcelable("dataPass", dataPass);
            mViewPager.getAdapter().notifyDataSetChanged();
        }
    }

    //My SectionsPagerAdapter inside the java file of the ActivityHome
    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        private Bundle bundleAdapter;

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        public SectionsPagerAdapter(FragmentManager fm, Bundle bundleAdapter) {
            super(fm);
            this.bundleAdapter = bundleAdapter;
        }


        //this is one of the latest tests carried out to update the Fragment
        @Override
        public void notifyDataSetChanged(){
            this.bundleAdapter = bundle;
            fragmentLeft = new FragmentLeft();
            FragmentTransaction ft =  getSupportFragmentManager().beginTransaction();
            fragmentLeft.setArguments(bundle);
            ft.replace(R.id.your_placeholder, fragmentLeft);
            ft.commit();
        }

        @Override
        public Fragment getItem(int position) {
            fragmentLeft = new FragmentLeft();
            fragmentRight = new FragmentRight();
            fragmentLeft.setArguments(bundleAdapter);
            fragmentRight.setArguments(bundleAdapter);
            switch (position) {
                case 0:
                    return fragmentLeft;
                case 1:
                    return fragmentRight;
                default:
                    return fragmentLeft;
            }
        } 

        @Override
        public int getCount() {
            // Show 2 total pages.
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Replace blank spaces with image icon
            SpannableString sb = new SpannableString(tabTitles[position]);
            return sb;
        }
    }

Расположение ActivityHome:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.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" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


    <FrameLayout
        android:id="@+id/your_placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>


    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/activity_home_drawer" />

</android.support.v4.widget.DrawerLayout>

РЕШИТЬ

Я нашел решение в этом посте Удалить страницу фрагмента из ViewPager в Android

У меня есть изменения FragmentPageAdapterс `FragmentStatePageAdapater

и переопределить этот метод:

@Override
public int getItemPosition(Object object) {
//FragmentLeft is the class for the first fragment in the view
//recreate only FragmentLeft
    if (object instanceof FragmentLeft) {
        return POSITION_NONE;
    }
    return 1;
}

Я снова предлагаю объяснение

Почему это решение работает

Переопределение getItemPosition ():

Когда notifyDataSetChanged()вызывается, адаптер вызывает notifyChanged()метод, к ViewPagerкоторому он подключен. В ViewPagerто проверяет значение , возвращенное в адаптере getItemPosition()для каждого элемента, удаляя те элементы , которые возвращают POSITION_NONE(просмотреть исходный код) , а затем репопулирующие.

Автор: Odino Источник Размещён: 18.07.2016 08:01

Ответы (3)


1 плюс

81 Репутация автора

1.Как вы отправляете новые данные на ваш пейджинговый адаптер представления (например, SectionsPagerAdapter). Я думаю, что вы не отправляете новые данные для обновления адаптера

Мое предложение: пожалуйста, попробуйте так

  1. Создайте одну функцию (например: refreshData (Bundle bundleAdapter)) в классе адаптера (SectionsPagerAdapter).

  2. поэтому с помощью этой функции вы можете отправить новые данные в adpater из вашего метода updateData ()

    1. mSectionsPagerAdapter .refreshData (bundleAdapter)

    2. mSectionsPagerAdapter .notifyDataSetChanged ();

Автор: Siva Размещён: 18.07.2016 08:21

0 плюса

81 Репутация автора

Пожалуйста, сохраните мою старую логику и теперь удалите регистр по умолчанию из регистра переключателя getItem (): измените логи, как показано ниже

public Fragment getItem(int position) {




        switch (position) {
            case 0:
            FragmentLeft fragmentLeft = new FragmentLeft();
             fragmentLeft.setArguments(bundleAdapter);
                return fragmentLeft;
            case 1:
              FragmentRight fragmentRight = new FragmentRight();
             fragmentRight.setArguments(bundleAdapter);
                return fragmentRight;

        }
    }
Автор: Siva Размещён: 18.07.2016 09:11

0 плюса

56 Репутация автора

Решение

РЕШИТЬ

Я нашел решение в этом посте Удалить страницу фрагмента из ViewPager в Android

У меня есть изменения FragmentPageAdapterс `FragmentStatePageAdapater

и переопределить этот метод:

@Override
public int getItemPosition(Object object) {
//FragmentLeft is the class for the first fragment in the view
//recreate only FragmentLeft
    if (object instanceof FragmentLeft) {
        return POSITION_NONE;
    }
    return 1;
}

Я снова предлагаю объяснение

Почему это решение работает

Переопределение getItemPosition ():

Когда notifyDataSetChanged()вызывается, адаптер вызывает notifyChanged()метод, к ViewPagerкоторому он подключен. В ViewPagerто проверяет значение , возвращенное в адаптере getItemPosition()для каждого элемента, удаляя те элементы , которые возвращают POSITION_NONE(просмотреть исходный код) , а затем репопулирующие.

Автор: Odino Размещён: 28.07.2016 06:10
Вопросы из категории :
32x32