我使用 FragmentStatePagerAdapter 的方式有什么问题?

What is wrong with how I am using a FragmentStatePagerAdapter?

我有一个 Activity 使用 FragmentStatePagerAdapter。如果我启动另一个 activity 更改与显示内容相关的一些数据,则视图不会更新。 如果适配器正在处理选项卡,每个选项卡都通过片段显示同一对象的不同方面, 如果对象属性被从适配器处理的页面启动的 activity 更改, 并且适配器 notifyDataSetChanged 在 onActivityResult 中被调用,选项卡视图中的数据没有得到更新,正如我所期望的那样。 我不明白为什么。

在activity class:

public class EventDetailActivity extends AppCompatActivity
{
    public ViewPager viewPager;
    public PagerAdapter adapter; // This extends FragmentStatePagerAdapter
    public TabLayout tabLayout;
    public Event currentEvent; // ****** Contains the data to display in tabs

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

        currentEvent = (Event)getIntent().getSerializableExtra(Event.EVENT_KEY); // ***** The object on display was serialized to pass in the intent.
        // Serializing it in the initial intent is not a problem, because it is saved in the database within this activity,
        // and the calling activity gets the update via the database.
        tabLayout = (TabLayout) findViewById (R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().
            setText(getResources().getString(R.string.details)));
        ... Add other tabs. ...
        tabLayout.setTabGravity (TabLayout.GRAVITY_FILL);
        viewPager = (ViewPager) findViewById (R.id.pager);
        adapter = new PagerAdapter(currentEvent, getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter (adapter);
        viewPager.addOnPageChangeListener (new TabLayout.TabLayoutOnPageChangeListener (tabLayout));
        tabLayout.setOnTabSelectedListener (new TabLayout.OnTabSelectedListener () {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem (tab.getPosition ());
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId ())
        {
            case R.id.menu_edit:
                Intent intent = new Intent(EventDetailActivity.this, EditEventActivity.class);
                intent.putExtra(Event.EVENT_KEY, currentEvent); // TODO Event via serialization, or event id only ?
                //intent.putExtra("id", currentEvent.getId());
                startActivityForResult(intent, EDIT_EVENT_REQUEST);
                return true;
            ... other cases
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data)
    {
        if (requestCode == EDIT_EVENT_REQUEST)
        {
            switch (resultCode)
            {
                case RESULT_CANCELED:
                    // Nothing to do
                    return;
                case RESULT_EVENT_MODIFIED:
                    // Cause event view for this activity to update.
                    // When the edit activity was started, the Event was serialized.
                    // An updated Event is passed back in the result.
                    //currentEvent = (Event)data.getSerializableExtra(Event.EVENT_KEY);
                    //System.out.println("Modified event returned: " + currentEvent.getEventTitle());
                    // Alternatively, Load the Event from the database:
                    try
                    {
                        HashMap attr = MyApp.getDatabase().getEventById(currentEvent.getId());
                        currentEvent.load(attr);
                        System.out.println("Event reloaded: " + currentEvent.getEventTitle());
                    }
                    catch (PersistenceException ex)
                    {
                        // TODO handle error
                    }
                    // FIXME: In both cases the received event is correct, but the UI is not updated.
                    // The adapter still references the object that was passed to the edit activity as serialized data
                    // So must give the adapter the object just deserialized/loaded here.
                    adapter.setEvent(currentEvent); // ***** notifyDataSetChanged() is called within this, but not updating the view !!!!!!!!
                    return;
                case RESULT_EVENT_UPDATE_FAILED:
                    // Nothing to do
                    return;
            }
        }
    }
    ...
}

适配器:

public class PagerAdapter extends FragmentStatePagerAdapter
{
    /** The event on display */
    private Event m_event;

    public PagerAdapter (Event event, FragmentManager fm)
    {
        super(fm);
        m_event = event;
    }

    public void setEvent (Event event)
    {
        m_event = event;
        notifyDataSetChanged(); // ****** Attempting to trigger update of displayed data, but the view does not update.
    }

    @Override
    public Fragment getItem (int position)
    {
        Fragment f;
        switch (position)
        {
            case 0:
                f = new DetailsFragment();
                break;
            ... other tab fragments
            default:
                return null;
        }
        // ******* FIXME?: The problem with passing serialized event to the fragment is that the fragment does not reference our event. 
        ... each fragment references a COPY of the event.
       // The updated event is passed back in the result... then set in the adapter.... BUT NOT IN FRAGMENTS 
       ... BUT FRAGMENTS GET CREATED HERE AS NECESSARY TO VIEW, AND WILL GET THE MODIFIED EVENT IN THIS ARGUMENTS BUNDLE:
       Bundle bundle = new Bundle();
       bundle.putSerializable(Event.EVENT_KEY, m_event);
       // Maybe just pass the event id in arguments, and the fragment gets the event from the database?? Sounds inefficient, and I think should not be necessary.
       //bundle.putLong(Event.EVENT_ID_KEY, m_event.getId());
       f.setArguments(bundle);
       return f;
    }
    ...
}

public class DetailsFragment extends Fragment
{
    /** Event to display */
    private Event m_event = null;

    ... UI TextView object declarations to show various attributes ...

    public DetailsFragment() {
        // Required empty public constructor
    }

    private void update ()
    {
        if (m_event == null)
        {
            ... set views empty ...
            return;
        }
        ... set views for attributes of m_event ...
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate (R.layout.fragment_event_details, container, false);

        //initalize widgets ...

        // Get event for view
        Bundle args = getArguments();
        m_event = (Event)args.getSerializable(Event.EVENT_KEY); // ***** Get the event passed in arguments to this fragment
        update();
        return view;
    }
}

FragmentStatePagerAdapter

中尝试 override 方法
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}