【问题标题】:Interface java/Android not working from child to parent fragment接口 java/Android 不能从子片段到父片段
【发布时间】:2016-03-18 02:05:07
【问题描述】:

我试图在两个片段中进行交流,主要片段和子片段。但是,当我在子片段中声明接口以将值传递给主片段时,它可以正常工作,但是当我想从主片段传递给子片段时,它不起作用。顺便说一句,片段在我的 MainActivity 中。 感谢您的帮助。

错误信息是:

Caused by: java.lang.IllegalArgumentException: com.example.example.example.MainActivity must implement interface NotifyOnTutorialPageSelected

那么有没有办法在不直接使用静态函数的情况下传递值?因为我注意到只有父级才能实现接口,所以如果我想用接口实现它该怎么办?顺便说一句,这是为了学习目的。

代码:

//MAin activity is something that calls only the mainfragment
public class MainActivity extends ActionBarActivity {

    FragmentManager fragmentManager;
    TutorialFragment tutorialFragment;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActionBar actionBar = getSupportActionBar();
        actionBar.hide();


        fragmentManager = getSupportFragmentManager();    
        fragmentManager.findFragmentById(R.id.card_message_frag);
        tutorialFragment = (TutorialFragment) fragmentManager.findFragmentById(R.id.tutorial_frag);

    }
}

FIRST CLASS(由 MainActivity 调用)

public class TutorialFragment extends Fragment implements ViewPager.OnPageChangeListener, OnTabSelected {

    FragmentManager fragmentManager;
    MultiTabFragment multiTabFragment;
    NotifyOnTutorialPageSelected notifyOnTutorialPageSelected;
    View tab ;
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_tutorial, container, false);
        fragmentManager = getChildFragmentManager();
        multiTabFragment = (MultiTabFragment) fragmentManager.findFragmentById(R.id.multi_tabs_frag);
        tab.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //Log.e("clicked tab# ", "" + tabIndex);
                        onTabSelected.onTabSelected(tabIndex);
                    }
                });
        return view;
    }

    @Override
    public void onPageSelected(int position) {  
        notifyOnTutorialPageSelected.notifyOnTutorialPageSelected(position); // do something so can communicate with the child fragment
    }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (getActivity() instanceof NotifyOnTutorialPageSelected) {
            notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getActivity();
        } else if (getParentFragment() instanceof OnTabSelected) {
            notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getParentFragment();
        } else {
            throw new IllegalArgumentException(activity + " must implement interface " + NotifyOnTutorialPageSelected.class.getSimpleName());
        }

    }

    @Override
    public void onDetach() {
        notifyOnTutorialPageSelected = null;
        super.onDetach();
    }

    @Override
    public void onTabSelected(int index) {
        Log.e("INDEX_PASSED", "" + index);
        pager.setCurrentItem(index);
    }
}

第二类(由 TutorialFragment 调用)

public class MultiTabFragment extends Fragment implements NotifyOnTutorialPageSelected{
    private OnTabSelected onTabSelected;

    final int totalTabs = 4;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.multi_tab_fragment, container, false);
        //...
        return view;
    }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (getActivity() instanceof OnTabSelected) {
            onTabSelected = (OnTabSelected) getActivity();
        } else if (getParentFragment() instanceof OnTabSelected) {
            onTabSelected = (OnTabSelected) getParentFragment();
        } else {
            throw new IllegalArgumentException(activity + " must implement interface " + OnTabSelected.class.getSimpleName());
        }
    }

    @Override
    public void onDetach() {
        onTabSelected = null;
        super.onDetach();
    }

    @Override
    public void notifyOnTutorialPageSelected(int index) {
        deselectPreviousTab(index);
    }

解决方案:

由于没有人回答这个问题,如果有人有类似的困难,我会在这里留下答案。我通过实现 MainActivity 的接口解决了这个问题,因此主活动将调用子类并调用方法:

//MAin activity is something that calls only the mainfragment
public class MainActivity extends ActionBarActivity implements NotifyOnTutorialPageSelected{

    FragmentManager fragmentManager;
    TutorialFragment tutorialFragment;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActionBar actionBar = getSupportActionBar();
        actionBar.hide();


        fragmentManager = getSupportFragmentManager();    
        fragmentManager.findFragmentById(R.id.card_message_frag);
        tutorialFragment = (TutorialFragment) fragmentManager.findFragmentById(R.id.tutorial_frag);

    }

@Override
    public void notifyOnTutorialPageSelected(int index) {
        FragmentManager fragmentChildManager = tutorialFragment.getChildFragmentManager();
        MultiTabFragment multiTabFragment = (MultiTabFragment) fragmentChildManager.findFragmentById(R.id.multi_tabs_frag);
        multiTabFragment.deselectPreviousTab(index);
    }
}

它对我有用,或者至少对我想要的有用,如果有人有不同的解决方案,请告诉我,谢谢。

【问题讨论】:

  • Here 已经回答了您的问题!
  • 谢谢你!我现在试试
  • notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getParentFragment();如果您的 notifyOnTutorialPageSelected 由子片段实现,您如何从父片段中询问该内容。它应该类似于 notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getChildFragment();
  • @dex 我刚刚更改了它,它仍然说我的主要活动必须实现该接口而不是子接口

标签: java android android-fragments interface


【解决方案1】:

您自己抛出异常是因为您的 Activity 未实现 NotifyOnTutorialPageSelected 接口,并且您的父片段不得实现 OnTabSelected 接口。

以下代码需要固定在前两个条件之一为真的地方。顺便说一句,您的 else if 语句中有一个潜在的错误,因为您只检查它是否是 instanceOf OnTabSelected,然后将父片段转换为 NotifyOnTutorialPageSelected

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (getActivity() instanceof NotifyOnTutorialPageSelected) {
            notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getActivity();
        } else if (getParentFragment() instanceof OnTabSelected) {
            notifyOnTutorialPageSelected = (NotifyOnTutorialPageSelected) getParentFragment();
        } else {
            throw new IllegalArgumentException(activity + " must implement interface " + NotifyOnTutorialPageSelected.class.getSimpleName());
        }

    }

查看您的代码,我看不到您如何拥有子片段,因为您的教程片段没有创建子片段。

您是否试图让一个 Activity 显示两个进行通信的片段?

如果是这样,请查看Android Documentation,了解如何使用界面进行操作。

编辑:

通过这次学习体验,您可能会发现您的代码存在更多错误。但是为了让您继续前进并摆脱当前的错误,请删除您的 TutorialFragment 片段中的 onAttach 方法,因为它无论如何都是错误的。如果你打算让你的Activity 类实现回调接口,那就是它要去的地方。由于您没有这样做,因此检查您的活动是否实现了该特定接口是没有意义的。

您的MultiTabFragment.onAttach 方法只需要以下内容,除非您有时要将片段直接放入活动中:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if (getParentFragment() instanceof OnTabSelected) {
        onTabSelected = (OnTabSelected) getParentFragment();
    } else {
        throw new IllegalArgumentException("Parent Fragment must implement interface " + OnTabSelected.class.getSimpleName());
    }
}

最后,由于您已经在 TutorialFragment 中保留了对 MultiTabFragment 的引用,请删除 NotifyOnTutorialPageSelected notifyOnTutorialPageSelected; 并直接调用片段。

@Override
public void onPageSelected(int position) {  
    multiTabFragment.notifyOnTutorialPageSelected(position); // do something so can communicate with the child fragment
}

【讨论】:

  • 它是,但我没有显示所有代码,主要活动包含 TutorialFragment 并且这包含 childFragment
  • 错误原因:java.lang.IllegalArgumentException:com.example.example.example.MainActivity@3d1d095 必须实现接口NotifyOnTutorialPageSelected
  • @kobbycoder 您没有正确设置活动和片段。正如我所提到的,您自己抛出了该异常,因为您的活动和父片段没有实现您期望的接口。
  • 那么 onTabSelected 是如何工作的?可以举个例子吗?
  • 您的代码目前的编写方式对我来说意义不大。您可以在问题中添加要添加片段的代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2023-03-30
  • 2019-03-17
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
相关资源
最近更新 更多