接口java / Android无法从子片段到父片段

时间:2015-12-12 02:57:43

标签: java android android-fragments interface

我正在尝试在两个片段(主要和孩子)之间进行交流。然而,当我声明孩子中的接口将值传递给主片段时,它工作正常,但是当我想从主片段传递到子片段时,它不起作用。顺便说一下片段在我的MainActivity中。 谢谢你的帮助。

错误消息是:

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

那么有没有办法直接传递值而不使用静态函数?因为我注意到只有父母可以实现界面所以如果我想用界面做什么我该怎么办呢?按照学习目的的方式。

CODE:

//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);

    }
}

第一类(由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);
    }
}

SECOND CLASS(由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);
    }

SOLUTION:

由于没有人回答这个问题,如果有人有类似的困难,我会在这里留下答案。我通过实现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);
    }
}

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

1 个答案:

答案 0 :(得分:1)

您自己抛出异常,因为您的活动没有实现NotifyOnTutorialPageSelected接口,并且您的父片段不能实现OnTabSelected接口。

以下代码需要修复到前两个条件之一为真的位置。顺便说一下你的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());
        }

    }

查看你的代码我没看到你是如何拥有子片段的,因为你的教程片段没有创建一个。

您是否尝试使用单个活动显示两个可以通信的片段?

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

编辑:

您可能会通过此学习体验发现您的代码存在更多错误。但为了让您前进并远离当前错误,请移除onAttach片段中的TutorialFragment方法,因为它无论如何都是错误的。如果你打算让你的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());
    }
}

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

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