2015-11-13 57 views
0

我已閱讀相關文章。在每個問題中,我都會看到活動的onActivityResult()至少會被調用。問題是如何將結果攜帶到碎片或嵌套碎片。但我面臨的問題是不同的。
我正在實現設置頁面,該頁面將包含來自新設計支持庫的TabLayout的選項卡。在我的應用程序中,我有一個包含其他碎片的Activity ...所以我添加了一個SettingsTabFragment,其中包含ViewPager和FragmentPagerAdapter。此適配器爲每個選項卡保留碎片。
其中一個選項卡是用戶配置文件設置,用戶可以在其中添加他的個人資料圖片。我用ACTION_PICKE意圖從子片段調用startActivityResult()。我重寫了Activity中的onActivityResult(),父段(保存視圖分頁器)和SettingsTabFragment。但是當我從畫廊選擇照片時,他們都沒有打電話。當從ViewPager中的子片段調用startActivityResult()時,不會調用onActivityResult()

當從以下位置調用startActivityResult()時,將無法調用onActivityResult():
- 子片段。
- 父代片段。我通過子片段getParentFragment()。startActivityResult()完成了此操作,並且也從父片段本身中直接附加到活動(不嵌套)。
- 使用getParentFragment()。getActivity()。startActivityResult()從子片段調用活動。

它們都不會導致至少調用onActivityResult()活動。

當我從片段調用startActivityResult()時,我確信我只調用了startActivityResult()..而不是getActivity()。startActivityResult()。

我以爲onActivityResult is not being called in Fragment,並嘗試了github lib中的一個答案建議,但似乎老闆告訴現在不推薦它。它也有編譯錯誤。

想不想呢?

+1

這是一個已知的限制。在Activity上調用'startActivityForResult()',或者在父代片段上調用'startActivityForResult()',並讓活動/父代片段將結果傳遞給子片段。 – CommonsWare

+0

我已經完成了使用回調。從子片段callBackToActivity.launchImagePicker()但沒有結果。我也嘗試從父母片段,但沒用。 – cgr

+0

我同意@CommonsWare最初onActivityResult的父活動將被調用。您需要覆蓋父代片段和父代活動的onActivityResult –

回答

4

在我的情況下,我通過在我的子分片類中使用意圖從聯繫人中提取手機號碼,即視圖分頁器的一個選項卡。

調用從MainActivity父片段:

//首頁是包含標籤的佈局和尋呼機查看我的父母片段。我通過指定標記來調用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將調用Parent fragment的i。 e。HomeFragment的onActivityResult方法。

在母體片段即家庭片段:

@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個孩子例如在查看傳呼機適配器IF段被添加,如:

@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 
} 
0

目前,這是一個known Android bug。在此之前就解決了一個解決辦法,可以用:

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); 
    } 
} 

在您的電話片段覆蓋startActivityForResult:

@Override 
public void startActivityForResult(final Intent _intent, final int _requestCode) { 
    FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
    HackForResultFragment f = HackForResultFragment.newInstance(_requestCode,_intent); 
    f.setCallingFragment(this); 
    fragmentManager.beginTransaction().add(f, null).commit(); 
} 
0

此錯誤現在已經得到解決,支持庫版本23.2.0,所以最好的辦法來解決這現在是升級支持庫。

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

+0

你可以編輯現有的答案?所以,我可以投票.. – cgr

+0

但我認爲我以前的答案也有價值 - 有些人可能不想升級他們的支持庫因各種原因 – Borg972

+0

在這種情況下,你可以結合更有用的答案..我想是這樣。 – cgr

0

如果FragmentActivity含有片段1,片段1包含fragment2。 Android只能處理fragment1.startActivityForResultfragment2.startActivityForResult將無法​​正常工作。

對於更多的細節和解決方案,看這個答案answer

相關問題