OnActivityResult не вызывать в фрагменте
Структура приложения такова:
tabHost (in Activity) -> contains -> TabFragment(extend base container fragment)
1. Код в действии:
tabHost.addTab(
tabHost.newTabSpec("home").setIndicator("",
getResources().getDrawable(R.drawable.btn_home)),
HomeFragment.class, null);
2. Код в HomeFragment
(Обратите внимание, что HomeFragment не является фактической функцией, а контейнером, подобным этому, и он расширяет BaseContainerFragment):
public class HomeFragment extends BaseContainerFragment {
public Home homeFrag;
private boolean mIsViewInited;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.container_fragment, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!mIsViewInited) {
mIsViewInited = true;
initView();
}
}
private void initView() {
homeFrag = new Home();
replaceFragment(homeFrag, false);
}
}
3. BaseContainerFragment
public class BaseContainerFragment extends Fragment {
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.container_framelayout, fragment);
transaction.commit();
}
public boolean popFragment() {
boolean isPop = false;
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
return isPop;
}
}
4. В Доме (фактическое содержание фрагмента)
UploadType fragment = new UploadType();
Bundle bundle = new Bundle();
bundle.putString("form_type", "request");
fragment.setArguments(bundle);
((BaseContainerFragment)getParentFragment()).replaceFragment(fragment, true);
5. И в UploadType я вызываю активность камеры, но onActivityResult возвращает только в основное действие.
startActivityForResult(intent, REQUEST_CAMERA);
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("test1", "result2");
super.onActivityResult(requestCode, resultCode, data);
}
Как я могу вызвать onActivityResult в UploadType? Спасибо за помощь.
Ответы
Ответ 1
Причина, по которой это не работает, заключается в том, что вы вызываете startActivityForResult()
из вложенного фрагмента. Android достаточно умен, чтобы вернуть результат обратно к Activity
и даже к Fragment
, но не к вложенному Fragment
, поэтому вы не получите обратный вызов.
(больше информации о том, почему это не работает здесь или на fooobar.com/questions/77399/...)
Теперь, чтобы сделать это, я предлагаю вам вручную перенаправить обратный вызов на ChildFragment
(= UploadType
) в ParentFragment
(= BaseContainerFragment
):
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment uploadType = getChildFragmentManager().findFragmentById(R.id.container_framelayout);
if (uploadType != null) {
uploadType.onActivityResult(requestCode, resultCode, data);
}
super.onActivityResult(requestCode, resultCode, data);
}
Ответ 2
В моем случае, я сделал, добавив следующий код в мой MainActivity.java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
Ответ 3
В вашей деятельности переопределите onActivityForResult(), как это
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Теперь в вашем фрагменте вы можете получить результат активности внутри этого
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("test1", "result2");
}
Убедитесь, что когда вы вызываете начало ActivityForResult в своем обрыве, это должно быть как
startActivityForResult(intent, REQUEST_CAMERA);
Ответ 4
TabActivity- > ActivityA- > FragmentB, он не работает.
используйте плохой плохой способ:
ActivityA.java
public void onSelectSomething(){
...
startActivityForResult(intent, 22222);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mFragment != null) {
mFragment.onActivityResult(requestCode, resultCode, data);
}
}
FragmentB.java
if(getActivity() instanceof ActivityA) {
((RepairerListActivity)getActivity()).onSelectSomething();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 22222) {
// do things
}
}
Ответ 5
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Loop through all child fragments of the activity
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
// check if the current fragment is YourFragment
if (fragment instanceof YourFragment ) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
}
Ответ 6
Для NavHostFragment компонента архитектуры навигации
Если вы используете одно действие и у вас есть фрагменты внутри NavHostFragment
, существует проблема onActivityResult()
дочернего фрагмента NavHostFragment
, который не вызывается.
Чтобы исправить эту проблему, вам нужно вызвать onActivityResult()
дочерних фрагментов вручную из onActivityResult()
основного действия. Хост-активность - это активность, на которой размещается ваш NavHostFragment
.
Вот код Kotlin для onActivityResult()
вашего хоста:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.your_nav_host_fragment)
val childFragments = navHostFragment?.childFragmentManager?.fragments
childFragments?.forEach { it.onActivityResult(requestCode, resultCode, data) }
}