Android 使用转换从片段启动活动(API 21支持)

Android 使用转换从片段启动活动(API 21支持),android,android-support-library,android-5.0-lollipop,onactivityresult,android-transitions,Android,Android Support Library,Android 5.0 Lollipop,Onactivityresult,Android Transitions,我正在尝试将一个Android应用程序移植到新的支持库(support-v4:21.0.0),但从带有转换的片段启动活动时遇到问题 在我的活动中,我一直在做以下事情: Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(this).toBundle(); ActivityCompat.startActivityForResult(this, intent, REQUEST_SOMETHING, options);

我正在尝试将一个Android应用程序移植到新的支持库(support-v4:21.0.0),但从带有转换的片段启动活动时遇到问题

在我的活动中,我一直在做以下事情:

Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(this).toBundle();
ActivityCompat.startActivityForResult(this, intent, REQUEST_SOMETHING, options);
这对活动很有效。但是,如果我尝试对片段执行类似的操作,例如:

Activity activity = getActivity();
Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity).toBundle();
ActivityCompat.startActivityForResult(activity, intent, REQUEST_SOMETHING, options);
事实证明,不会为片段调用
onActivityResult()
,而只调用封闭的活动。我在支持库中找不到任何东西可以将选项束作为参数传递给实际片段上的
startActivityForResult()
,并让它在该片段中回调到
onActivityResult()
。这可能吗

最简单的解决方案是处理活动本身中的所有
onActivityResult()
调用,但我不想这样做,因为我有大量可能接收回调的片段

谢谢你的帮助。谢谢

ActivityCompat#startActivityForResult()方法只是活动的
startActivityForResult(Intent,Bundle)
方法的代理。从fragment类内部调用该方法并不意味着
fragment
onActivityResult()
最终将被调用,我相信您已经发现了这一点。框架知道如何知道调用来自哪个类。。。在本例中,唯一正确的行为是调用
Activity
onActivityResult()
方法


听起来最好的选择是按照您在文章中的建议,在活动的
onActivityResult()方法中处理所有内容。

您可以在片段中创建一个侦听器接口或简单地创建一个公共函数,并传递从中获取onActivityResult()的参数将活动提交给侦听器或片段的公共方法,然后在那里完成您想要的工作。

遗憾的是,
活动compat.startActivityForResult()
片段
中不太正常(请参见Alex Lockwood的回答)。几周来,我一直惊叹于谷歌从未给我们提供一种与Fragment实现的
startActivityForResult()
相当的
ActivityCompat
方法。他们在想什么?!但后来我有了一个想法:让我们来看看这个方法是如何实际实现的。 事实上,片段中的
startActivityForResult()
与活动中的不同(请参阅):

现在
startActivityFromFragment()
看起来像这样(请参见):

将该方法复制到任何您喜欢的地方,并从片段中使用它。它的
onActivityResult()
将按其应该的方式调用

更新: 支持库v23.2已经发布,似乎
startActivityFromFragment(片段片段、意图、int-requestCode、捆绑选项)
现在就开始工作:)

一种简单的方法:

片段:

 ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation();

 this.startActivityFromFragment(this, intent, requestCode, options);

我理解为什么会发生这种情况,但这并没有减少任何不便。这是支持库中唯一没有的东西,还是本机片段也不能做到?我希望他们在将来添加此功能。您是否尝试过调用
片段
startActivityForResult(Intent,int,Bundle)
方法?使用您提供的上一个方法启动“结果活动”对我很有效-非常感谢您提供的解决方案,尽管我觉得它并不完全干净,所以,让我们希望谷歌不会改变关于奇怪字节移位的任何事情。我想从Activity调用,然后将结果从Activity传递到Fragment会更干净,但是如果将大量片段附加到我的Activity上(因为viewpager),则很难执行handle@user2302510确切地一个人处理这件事真的很让人困惑。很高兴它有帮助!
public void startActivityFromFragment(Fragment fragment, Intent intent, 
        int requestCode) {
    if (requestCode == -1) {
        super.startActivityForResult(intent, -1);
        return;
    }
    if ((requestCode&0xffff0000) != 0) {
        throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
    }
    super.startActivityForResult(intent,
                                 ((fragment.mIndex + 1) << 16) + (requestCode & 0xffff));
}
public static void startActivityForResult(Fragment fragment, Intent intent,
                                          int requestCode, Bundle options) {
    if (Build.VERSION.SDK_INT >= 16) {
        if ((requestCode & 0xffff0000) != 0) {
            throw new IllegalArgumentException("Can only use lower 16 bits" +
                                               " for requestCode");
        }
        if (requestCode != -1) {
            try {
                Field mIndex = Fragment.class.getDeclaredField("mIndex");
                mIndex.setAccessible(true);
                requestCode = ((mIndex.getInt(this) + 1) << 16) + (requestCode & 0xffff);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        ActivityCompat.startActivityForResult(fragment.getActivity(), intent,
                                              requestCode, options);
    } else {
        fragment.getActivity().startActivityFromFragment(this, intent, requestCode);
    }
}
 ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation();

 this.startActivityFromFragment(this, intent, requestCode, options);