当相机活动返回时,承载这个片段的活动有它的onActivityResult被调用。
我的片段开始一个活动的结果与意图发送给相机拍照。图片应用程序加载正常,拍摄照片并返回。然而onActivityResult从未被击中。我设置了断点,但什么都没有触发。一个片段可以有onActivityResult吗?我想是的,因为它是一个已提供的函数。为什么这个没有被触发?
ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 1888);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == 1888 ) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
}
}
选项1:
如果你从片段调用startActivityForResult(),那么你应该调用startActivityForResult(),而不是getActivity().startActivityForResult(),因为它将导致片段onActivityResult()。
如果你不确定你在哪里调用startActivityForResult()和你将如何调用方法。
选项2:
由于Activity获得onActivityResult()的结果,您将需要覆盖活动的onActivityResult()并调用super.onActivityResult()来传播到未处理的结果代码或所有的各自片段。
如果以上两个选项都不管用,那么请参考选项3,因为它肯定会起作用。
选项3:
从fragment显式调用onActivityResult函数如下所示。
在父Activity类中,重写onActivityResult()方法,甚至在Fragment类中重写同样的方法,并像下面的代码一样调用。
在父类中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
fragment.onActivityResult(requestCode, resultCode, data);
}
在儿童班:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// In fragment class callback
}
对于那些使用Android导航组件的人,应该在Activity的onActivityResult(…)中使用primaryNavigationFragment来获取它的片段引用,并调用fragment的fragment.onActivityResult(…)
下面是Activity的onActivityResult(…)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageData)
{
super.onActivityResult(requestCode, resultCode, imageData);
for (Fragment fragment : getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager().getFragments())
{
fragment.onActivityResult(requestCode, resultCode, imageData);
}
}
最简单的方法之一是从你的片段开始一个活动。
startActivity(ActivityName);
然后,添加你调用startActivityForResult(intent,"1");在你的Activity中添加onActivityResult
startActivityForResult(intent,"1");
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors
finish(); // finish the activity will get to back to your fragment.
}
我也面临着同样的问题,一旦我把这段代码从一个片段转移到一个实用工具类,将parentActivity作为参数传递,
Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);
然后我没有得到任何值在onActivityResult方法的片段,
之后,我把参数改为Fragment,所以修改后的method定义是这样的,
Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);
在那之后,我能够在片段上的onActivityResult中获得值
对于Android的导航组件,当你嵌套fragment时,这个问题就像一个无法解决的谜。
基于以下回答的知识和灵感,我想出了一个简单的解决方案:
在这篇文章中回答
在这篇文章中回答
在你的活动的onActivityResult()中,你可以循环使用FragmentManager的getFragments()方法获得的活动片段列表。
请注意,要做到这一点,您需要使用getSupportFragmentManager()或目标API 26及以上。
这里的想法是循环遍历列表,使用instanceof检查列表中每个Fragment的实例类型。
虽然循环这个Fragment类型的列表是理想的,但不幸的是,当你使用Android导航组件时,列表将只有一个项目,即NavHostFragment。
现在怎么办?我们需要让碎片知道NavHostFragment。NavHostFragment本身就是一个Fragment。因此,使用getChildFragmentManager(). getfragments(),我们再次得到一个List<Fragment>的片段已知我们的NavHostFragment。我们循环遍历这个列表,检查每个Fragment的实例。
一旦我们在列表中找到我们感兴趣的片段,我们就调用它的onActivityResult(),将活动的onActivityResult()声明的所有参数传递给它。
// Your activity's onActivityResult()
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
List<Fragment> lsActiveFragments = getSupportFragmentManager().getFragments();
for (Fragment fragmentActive : lsActiveFragments) {
if (fragmentActive instanceof NavHostFragment) {
List<Fragment> lsActiveSubFragments = fragmentActive.getChildFragmentManager().getFragments();
for (Fragment fragmentActiveSub : lsActiveSubFragments) {
if (fragmentActiveSub instanceof FragWeAreInterestedIn) {
fragmentActiveSub.onActivityResult(requestCode, resultCode, data);
}
}
}
}
}