Java 在新的嵌套片段API中未调用onActivityResult()
我一直在使用Android支持库中包含的新API 对于嵌套片段,我面临的问题是,如果一个嵌套片段(即通过Java 在新的嵌套片段API中未调用onActivityResult(),java,android,kotlin,android-fragments,android-nested-fragment,Java,Android,Kotlin,Android Fragments,Android Nested Fragment,我一直在使用Android支持库中包含的新API 对于嵌套片段,我面临的问题是,如果一个嵌套片段(即通过getChildFragmentManager()返回的FragmentManager添加到另一个片段的片段)调用startActivityForResult(),则嵌套片段的onActivityResult()方法未被调用。但是,父片段的onActivityResult()和活动的onActivityResult()都会被调用 我不知道我是否遗漏了嵌套片段的某些内容,但我没有预料到所描述的行
getChildFragmentManager()
返回的FragmentManager
添加到另一个片段的片段)调用startActivityForResult()
,则嵌套片段的onActivityResult()
方法未被调用。但是,父片段的onActivityResult()
和活动的onActivityResult()
都会被调用
我不知道我是否遗漏了嵌套片段的某些内容,但我没有预料到所描述的行为。下面是重现此问题的代码。如果有人能给我指出正确的方向并向我解释我做错了什么,我将不胜感激:
package com.example.nestedfragmentactivityresult;
导入android.media.ringtonemager;
导入android.os.Bundle;
导入android.content.Intent;
导入android.support.v4.app.Fragment;
导入android.support.v4.app.FragmentActivity;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.Button;
导入android.widget.Toast;
公共类MainActivity扩展了FragmentActivity
{
创建时的公共void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
此文件名为.getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content,新的ContainerFragment())
.commit();
}
ActivityResult上的公共void(int请求代码、int结果代码、意图数据)
{
super.onActivityResult(请求代码、结果代码、数据);
//这叫做
Toast.makeText(getApplication(),
“被活动消耗”,
吐司。长度(短)。show();
}
公共静态类ContainerFragment扩展了片段
{
创建视图上的公共最终视图(更平坦的充气机,
视图组容器,
Bundle savedInstanceState)
{
查看结果=充气机。充气(R.layout.test\u嵌套的\u碎片\u容器,
集装箱,
假);
返回结果;
}
已创建ActivityState上的公共无效(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
getChildFragmentManager().beginTransaction()
.add(R.id.content,new NestedFragment())
.commit();
}
ActivityResult上的公共无效(int请求代码,
int结果代码,
意图(数据)
{
super.onActivityResult(请求代码、结果代码、数据);
//这叫做
Toast.makeText(getActivity(),
“被父片段消耗”,
吐司。长度(短)。show();
}
}
公共静态类NestedFragment扩展了片段
{
创建视图上的公共最终视图(更平坦的充气机,
视图组容器,
Bundle savedInstanceState)
{
按钮按钮=新按钮(getActivity());
button.setText(“单击我!”);
setOnClickListener(新视图.OnClickListener()
{
公共void onClick(视图v)
{
意向意向=新意向(铃声管理器.操作\u铃声\u选择器);
startActivityForResult(意向,0);
}
});
返回按钮;
}
ActivityResult上的公共无效(int请求代码,
int结果代码,
意图(数据)
{
super.onActivityResult(请求代码、结果代码、数据);
//这不叫
Toast.makeText(getActivity(),
“被嵌套片段消耗”,
吐司。长度(短)。show();
}
}
}
test_nested_fragment_container.xml是:
是的,嵌套片段中的
onActivityResult()
将不会以这种方式调用
onActivityResult(在Android支持库中)的调用顺序为
Activity.dispatchActivityResult()
FragmentActivity.onActivityResult()
Fragment.onActivityResult()
李>
在第三步中,在父级活动
的碎片管理器
中找到碎片。因此,在您的示例中,发现在ActivityResult()上分派的是容器片段,嵌套片段永远无法接收事件
我认为您必须在ContainerFragment.onActivityResult()中实现自己的分派,找到嵌套的片段并调用它,然后将结果和数据传递给它。下面是我如何解决它的
在活动中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
List<Fragment> frags = getSupportFragmentManager().getFragments();
if (frags != null) {
for (Fragment f : frags) {
if (f != null)
handleResult(f, requestCode, resultCode, data);
}
}
}
private void handleResult(Fragment frag, int requestCode, int resultCode, Intent data) {
if (frag instanceof IHandleActivityResult) { // custom interface with no signitures
frag.onActivityResult(requestCode, resultCode, data);
}
List<Fragment> frags = frag.getChildFragmentManager().getFragments();
if (frags != null) {
for (Fragment f : frags) {
if (f != null)
handleResult(f, requestCode, resultCode, data);
}
}
}
@覆盖
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
List frags=getSupportFragmentManager().getFragments();
if(frags!=null){
用于(碎片f:碎片){
如果(f!=null)
HandlerResult(f、请求代码、结果代码、数据);
}
}
}
私有void handleResult(片段片段、int请求代码、int结果代码、意图数据){
if(IHandleActivityResult的frag实例){//无符号的自定义接口
frag.onActivityResult(请求代码、结果代码、数据);
}
List frags=frag.getChildFragmentManager().getFragments();
if(frags!=null){
用于(碎片f:碎片){
如果(f!=null)
HandlerResult(f、请求代码、结果代码、数据);
}
}
}
我也面临同样的问题!我
private static ChildFragment mChildFragment;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mChildFragment.onActivityResult(int requestCode, int resultCode, Intent data);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
List<Fragment> fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
}
getParentFragment().startActivityForResult(intent, requestCode);
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) }
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent result) {
super.onActivityResult(requestCode, resultCode, result);
if (requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
beginCrop(result.getData());
} }
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, 103);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 101 && resultCode == getActivity().RESULT_OK && null != data) {
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));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mFragments.noteStateNotSaved();
int index = requestCode>>16;
if (index != 0) {
index--;
final int activeFragmentsCount = mFragments.getActiveFragmentsCount();
if (activeFragmentsCount == 0 || index < 0 || index >= activeFragmentsCount) {
Log.w(TAG, "Activity result fragment index out of range: 0x"
+ Integer.toHexString(requestCode));
return;
}
final List<Fragment> activeFragments =
mFragments.getActiveFragments(new ArrayList<Fragment>(activeFragmentsCount));
Fragment frag = activeFragments.get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
} else {
frag.onActivityResult(requestCode&0xffff, resultCode, data);
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
public abstract class NestedFragment extends Fragment {
@Override
public void startActivityForResult(Intent intent, int requestCode) {
List<Fragment> fragments = getFragmentManager().getFragments();
int index = fragments.indexOf(this);
if (index >= 0) {
if (getParentFragment() != null) {
requestCode = ((index + 1) << 8) + requestCode;
getParentFragment().startActivityForResult(intent, requestCode);
} else {
super.startActivityForResult(intent, requestCode);
}
}
}
public abstract class MyFragment extends Fragment {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
int index = requestCode >> 8;
if (index > 0) {
//from nested fragment
index--;
List<Fragment> fragments = getChildFragmentManager().getFragments();
if (fragments != null && fragments.size() > index) {
fragments.get(index).onActivityResult(requestCode & 0x00ff, resultCode, data);
}
}
}