从ViewPager

时间:2015-11-13 17:20:05

标签: android android-viewpager fragment onactivityresult

我已阅读相关帖子。在每个问题中,我都看到至少调用了活动的onActivityResult()。问题是如何将结果传递给片段或嵌套片段。但我面临的问题是不同的 我正在实现“设置”页面,该页面将包含来自新设计支持库的TabLayout选项卡。在我的应用程序中,我有一个Activity,其中包含其他片段...所以我添加了一个SettingsTabFragment,其中包含ViewPager和FragmentPagerAdapter。此适配器为每个选项卡保存片段。
其中一个选项卡是用户配置文件设置,用户可以在其中添加其配置文件图我用ACTION_PICK意图从子片段调用了startActivityResult()。我重写了Activity中的onActivityResult(),父片段(包含视图寻呼机)和SettingsTabFragment。但是当我从画廊中选择图片时,没有一个被调用。

当startActivityResult()调用时,onActivityResult()都不会被调用:
- 儿童片段。
- 父片段。我是从子frag getParentFragment()。startActivityResult()AND中做到这一点,也来自父片段本身,它直接附加到activity(非嵌套)。
- 使用来自子片段的活动调用getParentFragment()。getActivity()。startActivityResult()。

它们都没有导致至少调用活动的onActivityResult()。

当我从片段调用startActivityResult()时,确保我只调用了startActivityResult()..而不是getActivity()。startActivityResult()。

我跟着onActivityResult is not being called in Fragment并尝试了其中一个答案中建议的github lib,但似乎老板告诉它现在不推荐。它也有编译错误。

对它的想法?

4 个答案:

答案 0 :(得分:1)

在我的情况下,我是通过在我的子片段类中使用intent来从联系人中获取手机号码,即查看寻呼机的标签之一。

从MainActivity调用父片段:

// Home是我的父片段,其中包含Tab Layout和View Pager。我通过指定标签来调用Home Fragment,稍后我将使用此标记。

Fragment fragment = new Home();
fragmentManager.beginTransaction()
               .replace(R.id.main_content, fragment, "MobileTag")
               .addToBackStack(null)
               .commit();

在我的孩子片段类:

Intent intent = new Intent(Intent.ACTION_PICK, 
                           ContactsContract.Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);

现在它将调用MainActivity类的onActivityResult方法 在主要活动中:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

通过在MainActivity的onActivityResult中调用super,将调用Parent片段,即Home Fragment的onActivityResult方法。

在父片段中,即Home Fragment:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getFragmentManager()
        .findFragmentByTag("MobileTag")
        .getChildFragmentManager()
        .getFragments()
        .get(0);
    fragment.onActivityResult(requestCode, resultCode, data);
}

这里我得到父片段的第0个孩子,例如在View Pager适配器中添加片段如:

@Override
public Fragment getItem(int position) {
    switch (position){
        case 0 :return new ChildFragment0();
        case 1 : return new ChildFragment1();
        case 2 : return new ChildFragment2();
    }
    return null;
}

然后

getFragmentManager()
   .findFragmentByTag("MobileTag")
   .getChildFragmentManager()
   .getFragments()
   .get(0); // will return ChildFragment0

之后调用子片段的onActivityResult方法:

最后是儿童片段:

public void onActivityResult(int reqCode, int resultCode, Intent data) {
    Cursor cursor = null;
    String contactNumber = "";           
    Uri result = data.getData();
    // get the result here
}

答案 1 :(得分:0)

目前,它是known Android bug。在解决此问题之前,可以使用解决方法:

------------------------------------ config.php ----------------------------

    $config['base_url'] = '';
    $config['index_page'] = '';
    $config['uri_protocol'] = 'REQUEST_URI';// if this will not work. comment this line and remove comment from below line
 // $config['uri_protocol'] = 'AUTO'; 

---------------------------------- .htaccess -----------------------------

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* index.php/$0 [PT,L]

在你的调用片段覆盖startActivityForResult:

public class HackForResultFragment extends Fragment {

    private static Fragment _callingFragment;

    private Intent _intent;
    private int _requestCode;


    public static HackForResultFragment newInstance(int _requestCode, Intent _intent){

        HackForResultFragment fragment = new HackForResultFragment();
        Bundle bundle = new Bundle(2);
        bundle.putInt("_requestCode", _requestCode);
        bundle.putParcelable("_intent", _intent);
        fragment.setArguments(bundle);
        return fragment;
    }

    public HackForResultFragment() {
    }

    public void setCallingFragment(Fragment callingFragment){
        _callingFragment = callingFragment;
    }

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

        Bundle arguments = getArguments();
        if (arguments == null) {
            //Error handling
            LogUtil.Error("arguments should have been passed to HackForResultFragment");
        }
        else {
            _requestCode = arguments.getInt("_requestCode");
            _intent = arguments.getParcelable("_intent");
        }

        if (savedInstanceState == null) { //first time only
            startActivityForResult(_intent, _requestCode);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (_requestCode == requestCode) {

            if (_callingFragment != null) {
                _callingFragment.onActivityResult(requestCode, resultCode, data);
                _callingFragment = null;
            }
        }
        getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putBoolean("startActivityForResultAlreadyCalled",true);
    }
}

答案 2 :(得分:0)

此错误现已在支持库版本23.2.0中得到解决,因此现在解决此问题的最佳方法是升级支持库。

来源:https://code.google.com/p/android/issues/detail?id=40537#c40

答案 3 :(得分:0)

如果FragmentActivity包含fragment1,则fragment1包含fragment2。 Android只能处理fragment1.startActivityForResultfragment2.startActivityForResult无效。

有关更多详细信息和解决方案,请观看此答案answer