使用TabLayout和FragmentPagerAdapter从活动中收到的新数据更新/重新加载片段

时间:2016-07-18 08:01:20

标签: android android-layout android-fragments

我的应用程序包含一个ActivityHome,使用TabLayoutSectionsPagerAdapter extends FragmentPagerAdapter将占位符插入两个内部片段(FragmentLeft和FragmentRight)。

ActivityHome从数据库加载数据,并使用SectionsPagerAdapter中的getItem方法将它们传递给两个片段中的bundle(几乎是基础SectionsPagerAdapter)

FragmentRight创建一个弹出窗口,其中包含另一个片段(FragmentPopup)。该片段为用户提供了通过UPDATE查询进行更改并将所有内容保存到数据库的可能性

这些数据显示在FragmentLeft和FragmentRight中,我希望在通过FragmentPopup更新数据库时更新它们。

为此,我在FragmentPopup(interfaceDataFragmentPopUpToActivity)中定义了一个接口,该接口在HomeActivity中实现。通过此接口,ActivityHome可以看到数据已被修改并更新将在两个片段中传递的数据。这个数据更新在ActivityHome中执行,并实现了我的接口方法。 另外,我已经覆盖了SectionsPagerAdapter类的notifyDataSetChanged()方法,试图更新这两个片段。 问题是我无法正确地为片段充电(我对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>

解决

我在这篇文章Remove Fragment Page from ViewPager in Android

中找到了解决方案

我已使用`FragmentStatePageAdapater

更改FragmentPageAdapter

并覆盖此方法:

@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()的{​​{1}}方法。然后ViewPager检查适配器ViewPager为每个项返回的值,删除那些返回getItemPosition()的项(请参阅源代码),然后重新填充。

3 个答案:

答案 0 :(得分:1)

1.如何向视图寻呼机适配器发送新数据(即SectionsPagerAdapter)。我认为您没有发送新数据来刷新适配器

我的建议:请尝试这样

  1. 请在适配器(SectionsPagerAdapter)类中创建一个函数(例如:refreshData(Bundle bundleAdapter))。

  2. 因此,通过使用该功能,您可以从updateData()方法将新数据发送到adpater

    1. mSectionsPagerAdapter .refreshData(bundleAdapter)

    2. mSectionsPagerAdapter .notifyDataSetChanged();

答案 1 :(得分:0)

请保留我的旧逻辑,现在从getItem()开关案例中删除默认情况:更改下面的logi

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;

        }
    }

答案 2 :(得分:0)

<强>解决

我在这篇文章Remove Fragment Page from ViewPager in Android

中找到了解决方案

我已使用`FragmentStatePageAdapater

更改FragmentPageAdapter

并覆盖此方法:

@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()的{​​{1}}方法。然后ViewPager检查适配器ViewPager为每个项返回的值,删除那些返回getItemPosition()的项(请参阅源代码),然后重新填充。