简体   繁体   English

接口Java / Android无法从子级到父级片段工作

[英]Interface java/Android not working from child to parent fragment

I am trying to communicate within two fragments, the main and the child. 我试图在两个方面进行沟通,主要和孩子。 however when i declare the interface in the child to pass values to the main fragment it works fine but when i want to pass from the main to the childfragment it doesn't work. 但是,当我在子级中声明接口以将值传递给主片段时,它工作正常,但是当我要从主级传递到子片段时,它不起作用。 by the way the fragment is in my MainActivity. 顺便说一句,片段在我的MainActivity中。 Thanks for your help. 谢谢你的帮助。

The error message is: 错误消息是:

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

so is there a way to pass value without using static function directly? 有没有直接使用静态函数的方法来传递值? because what i have noticed that only the parent can implement the interface so what can i do it if i want to make it with interface? 因为我已经注意到只有父母可以实现接口,所以如果我想通过接口实现该怎么办? by the way it is for learning purposes. 顺便说一句,这是出于学习目的。

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

    }
}

FIRST CLASS (called by MainActivity) 头等舱(由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 (called by TutorialFragment) 第二类(由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: 解:

Since nobody answered the question I will leave the answer right here if someone has similar difficulty. 由于没有人回答问题,如果有人遇到类似的困难,我将在此处保留答案。 I solved this problem by implementing the interface to the MainActivity so the main activity would call the childclass and call the method: 我通过实现MainActivity的接口解决了这个问题,因此主要活动将调用childclass并调用方法:

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

it worked for me or at least for what i wanted, if someone has a different solution please tell me, Thanks. 它对我有用,或者至少对我想要的有用,如果有人有其他解决方案,请告诉我,谢谢。

You are throwing the exception yourself because your activity does not implement the NotifyOnTutorialPageSelected interface and your parent fragment must not implement the OnTabSelected interface. 您自己NotifyOnTutorialPageSelected了异常,因为您的活动未实现NotifyOnTutorialPageSelected接口,并且您的父片段不得实现OnTabSelected接口。

The following code needs to be fixed to where one of the first two conditions is true. 以下代码需要固定为前两个条件之一为真的位置。 You have a potential mistake in your else if statement by the way since you are only checking if it is an instanceOf OnTabSelected but then cast the parent fragment as a NotifyOnTutorialPageSelected : 顺便说一下,您的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());
        }

    }

Looking at your code I do not see how you have a child fragment since your tutorial fragment is not creating one. 查看您的代码,因为您的教程片段没有创建一个子片段,所以我看不到您有一个子片段。

Are you trying to have a single activity that displays two fragments that communicate? 您是否要让一个活动显示两个可以通信的片段?

If so take a look at the Android Documentation on how to do that using an interface. 如果是这样,请查看Android文档 ,了解如何使用界面进行操作。

EDIT: 编辑:

You are likely going to find through this learning experience that there is a lot more wrong with your code. 通过这种学习经验,您可能会发现代码有很多错误。 But to get you moving forward and away from your current error remove the onAttach method in your TutorialFragment fragment since it is wrong anyway. 但是onAttach您前进并远离当前的错误,请删除TutorialFragment片段中的onAttach方法,因为无论如何它都是错误的。 If you are going to have your Activity class implement the callback interfaces that is where it would go. 如果您要让Activity类实现将要使用的回调接口。 Since you aren't doing it that way then there is no point in checking if your activity implements that particular interface. 由于您未按照这种方式进行操作,因此没有必要检查您的活动是否实现了该特定接口。

Your MultiTabFragment.onAttach method only needs the following unless you are going to put the fragment directly into an activity sometimes: 您的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());
    }
}

Finally since you are already keeping a reference to your MultiTabFragment in your TutorialFragment remove the NotifyOnTutorialPageSelected notifyOnTutorialPageSelected; 最后,由于您已经在TutorialFragment中保留了对MultiTabFragment的引用,因此请删除NotifyOnTutorialPageSelected notifyOnTutorialPageSelected; and call to the fragment directly. 并直接调用该片段。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM