Android setShareIntent within fragment

2020-04-18 06:14发布

问题:

1. Background

I have a screen that has a

ShareActionProvider

and a

ViewPager

that uses fragments.

What I was hoping to do was get some information from inside the currently visible fragment to create an intent, I would then be able to set the intent on the ShareActionProvider.

This is the code I use to set the intent of the ShareActionProvider:

    MenuItem actionItem = men.getMenu().findItem(R.id.menu_item_share_action_provider_action_bar);
    ShareActionProvider actionProvider = (ShareActionProvider) actionItem.getActionProvider();
    actionProvider.setShareIntent(createShareIntent(mProduct.mProduct));

I have tried using this in several places such as within these functions of the Fragment class :

onCreateView
onStart

I have also tried using it in these functions within the FragmentPagerAdapter class :

getItem

2. The Problem

Although the intent is actually getting set within the ShareActionProvider, the information that is obtained is for the next fragment (the one not currently being shown). For example:

If I have 4 fragments : frag1, frag2, frag3, frag4 and I am currently viewing "frag1" the ShareActionProvider will attempt to share "frag2". This is true until it reaches "frag4" where it will share the correct value.

My guess is that the fragment pager creates the current view and the next view (hidden), which is in turn setting the ShareActionProvider. If this is the case then where is the correct place to "setShareIntent"?

回答1:

I stumble on this question while dealing with similar problem. 2 things about accepted solution:

  1. Don't save reference to the fragment anywhere, especially in some list in the adapter
  2. Don't create fields in the fragment, always store data you need in the Bundle so you can get it by using Fragment#getArguments

Now - with this in mind here's a simple solution: put your ShareActionProvider initialization code to onPrepareOptionsMenu call. Something like this:

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem menuShare = menu.findItem(R.id.menuShare);
    ShareActionProvider shareAction = (ShareActionProvider) 
         menuShare.getActionProvider();
    shareAction.setShareIntent(createShareIntent());
}

protected Intent createShareIntent() {
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    Job job = getArguments().getSerializable(JOB);
    shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, job.title);
    shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, job.toText());
    return shareIntent;
}


回答2:

I managed to figure out how to do this myself. What I ended up doing is overriding the

OnPageChangeListener

in the fragmentactivity

private final OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {

    @Override
    public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPageSelected(int arg0) {
        // TODO Auto-generated method stub
        TestFragment frag = (TestFragment) adapter.mFragments.get(pager.getCurrentItem());

        frag.setShareActionIntent();

    }

};


回答3:

http://developer.android.com/reference/android/widget/ShareActionProvider.html

the example from android sdk doc is:

  // In Activity#onCreateOptionsMenu
  public boolean onCreateOptionsMenu(Menu menu) {
      // Get the menu item.
      MenuItem menuItem = menu.findItem(R.id.my_menu_item);
      // Get the provider and hold onto it to set/change the share intent.
      mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
      // Set history different from the default before getting the action
      // view since a call to MenuItem.getActionView() calls
      // onCreateActionView() which uses the backing file name. Omit this
      // line if using the default share history file is desired.
      mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
      . . .
  }

  // Somewhere in the application.
  public void doShare(Intent shareIntent) {
      // When you want to share set the share intent.
      mShareActionProvider.setShareIntent(shareIntent);
  }