向Fragment传递接口

23

让我们考虑这样一个情况,我拥有 片段A片段B

B 声明:

public interface MyInterface {
    public void onTrigger(int position);
}

A 实现了这个接口。

当将 Fragment B 推入堆栈时,我应该如何在 Bundle 中传递对它的 Fragment A 的引用,以便 A 在需要时可以获得 onTrigger 回调。

我的用例场景是,A 有一个带有项目的 ListView,而 B 有一个带有项目的 ViewPager。两者包含相同的项目,当用户从 B->A 转换时,在弹出 B 之前,应触发 A 的回调,以将其 ListView 位置更新为与 B pager 位置匹配。

谢谢。

6个回答

33
Passing interface to Fragment

我认为你正在两个Fragment之间进行通信

为了实现这一点,你可以参考与其他Fragment通信

public class FragmentB extends Fragment{
    MyInterface mCallback;

    // Container Activity must implement this interface
    public interface MyInterface {
        public void onTrigger();
    }

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

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (MyInterface ) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement MyInterface ");
        }
    }

    ...
}

10
但是我的Activity与想要通信的这两个Fragment没有任何关系,难道没有其他解决方案吗? - Niko
@Niko,你能否再详细解释一下并提供一些用户界面,这样我就可以帮助你了。 - Amit Gupta
我更新了我的问题,并添加了使用案例。 - Niko
1
Android文档的链接帮助我完成了这个。 - EdmundYeung99

6

针对Kotlin 1.0.0-beta-3595版本

interface SomeCallback {}

class SomeFragment() : Fragment(){

    var callback : SomeCallback? = null //some might want late init, but I think this way is safer

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        callback = activity as? SomeCallback //returns null if not type 'SomeCallback'

        return inflater!!.inflate(R.layout.frag_some_view, container, false);
    }
}

1
最优的做法是让两个片段只通过活动进行通信。因此,您可以在片段B中定义一个由活动实现的接口。然后在活动中,在接口方法中定义您希望在片段A中发生的内容。
在片段B中,
MyInterface mCallback;
 public interface MyInterface {
        void onTrigger(int position);
    }

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (MyInterface) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement MyInterface");
        }
}

判断用户是否从B到A的方法

public void onChangeFragment(int position){
//other logic here
 mCallback.onTrigger(position);
}

在活动中,
public void onTrigger(int position) {
    //Find listview in fragment A
    listView.smoothScrollToPosition(position);
    }

祝你好运!


0

使用 @Amit 的答案,并根据 OP 的问题进行调整,以下是所有相关代码:

public class FragmentA extends BaseFragment implements MyInterface {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // THIS IS JUST AN EXAMPLE OF WHERE YOU MIGHT CREATE FragmentB
        FragmentB myFragmentB = new FragmentB();        
    }


    void onTrigger(int position){
        // My Callback Happens Here!
    }
}

...

public class FragmentB extends BaseFragment {

    private MyInterface callback;

    public interface MyInterface {
        void onTrigger(int position);
    }   

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

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            callback = (MyInterface ) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement MyInterface");
        }
    }
}

1
在Fragment A中我做了同样的事情,但是没有得到回调,但是在Activity中我得到了回调。 - Hitesh Danidhariya

0

您可以通过这种方式创建回调接口。

 var screenVisibility=activity as YourActivity
 screenVisibility.setScreenVisibility("which screen you want")

0

我认为你应该使用通信,就像我下面写的那样。这段代码来自Android Dev页面中关于Fragment之间通信的部分

HeadlinesFragment

public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;

public void setOnHeadlineSelectedListener(Activity activity) {
    mCallback = activity;
}

// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
    public void onArticleSelected(int position);
}

// ...
}

主活动

public static class MainActivity extends Activity
    implements HeadlinesFragment.OnHeadlineSelectedListener{
// ...

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof HeadlinesFragment) {
        HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment;
        headlinesFragment.setOnHeadlineSelectedListener(this);
    }
}

public static class MainActivity extends Activity
    implements HeadlinesFragment.OnHeadlineSelectedListener {
...

public void onArticleSelected(int position) {
    // The user selected the headline of an article from the HeadlinesFragment
    // Do something here to display that article
}

与其提供链接,将最相关的部分作为引用块包含在您的回答中,并提供链接作为参考会更有帮助。 - MyStackRunnethOver
@MyStackRunnethOver 我已经完成了。 - ardiien
啊,代码就是引用。那么也许你的第一行应该是:“我认为你应该使用通信,就像我下面写的那样。这段代码来自于Android开发者关于通信的页面。” - MyStackRunnethOver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接