使用接口在Activity和Fragment之间传递数据

5
我想使用接口将数据从一个活动传递到一个碎片中。请查看下面的代码片段:
接口:
public interface FragmentCommunicator {

   public void passData(String name);
}

主活动:

public class MainActivity extends AppCompatActivity{

    FragmentCommunicator fragmentCommunicator;
    private Fragment fragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button b = (Button) findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fragment= new Fragment();
                fragmentCommunicator = (FragmentCommunicator) getApplication();
                fragmentCommunicator.passData("hello");
                getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment).commit();

            }
        });

    }
}

片段:
public class Fragment extends android.support.v4.app.Fragment implements FragmentCommunicator {

    FragmentCommunicator communicator;
    Context c;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, null);

        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.c = context;

    }
    @Override
    public void passData(String name) {
        Toast.makeText(c, name, Toast.LENGTH_SHORT).show();
    }
}

当我点击按钮(或其他事件)启动一个片段时,我只想传递一些字符串,并且当片段被启动时,它应该显示一个包含该字符串的toast...请帮忙。任何帮助都将不胜感激。

如何从Activity跳转到Fragment - https://dev59.com/rGox5IYBdhLWcg3wYzQt#9245510 - AgileNinja
@AgileNinja,我说过我想要使用接口传递数据,而不是使用Bundle。 - Akshay Sood
3个回答

10
在onCreate方法后编写以下代码。
public void passVal(FragmentCommunicator fragmentCommunicator) {
    this.fragmentCommunicator = fragmentCommunicator;
}

像这样的东西

public class MainActivity extends AppCompatActivity{

FragmentCommunicator fragmentCommunicator;
private Fragment fragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button b = (Button) findViewById(R.id.button);

    fragment= new Fragment();

    //App is crasing for this line. Working fine by removing it
    //fragmentCommunicator = (FragmentCommunicator) getApplication();

    //fragmentCommunicator.passData("hello");
    getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment).commit();

    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            fragmentCommunicator.passData("Hello");

        }
    });

  }

   //Here is new method
   public void passVal(FragmentCommunicator fragmentCommunicator) {
       this.fragmentCommunicator = fragmentCommunicator;

   }
}

然后将这行代码写入您的片段的onCreateView()中。就像这样:

@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup  container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null);

((MainActivity) getActivity()).passVal(new FragmentCommunicator() {
       @Override
       public void passData(String name) {
           Toast.makeText(c, name, Toast.LENGTH_SHORT).show();
       }
   });
  return view;
}

注意:您的片段无需实现FragmentCommunicator接口。希望它能起作用。我已经测试过了,它对我起作用。


代码已更新,请重试。 - Masum
1
java.lang.ClassCastException: android.app.Application 无法转换为 com.example.akshaysood.interfacecallback.FragmentCommunicator - Akshay Sood
你想通过按任意按钮或片段初始时间传递值吗? - Masum
我想在点击按钮时传递值,并同时启动片段。 - Akshay Sood
fragmentCommunicator = (FragmentCommunicator) getApplication(); 这行代码的作用是什么? - Kanagalingam
显示剩余4条评论

1

活动包含片段,您不需要传递任何内容。一种技术是将数据存储在活动范围内,并使用getActivity()引用它。

最佳实践:引用片段的父活动?

就您发布的代码而言,我没有看到您在片段中调用传递数据方法的地方。建议在onviewcreated()中调用它。

尝试passdata(getActivity().someStringVariable);


我该如何传递数据和访问数据,你能写一个简单的例子吗? - Akshay Sood

0
在你的Fragment类中,有一个TAG字段。将一个片段命名为Fragment可能会有点令人困惑,因为它与Android的Fragment具有相同的名称,所以我将使用ExampleFragment
public class ExampleFragment extends android.support.v4.app.Fragment implements FragmentCommunicator {
    public static final String TAG = "ExampleFragment";

    // ...
}

现在,在活动中替换片段时,请确保传递TAG
getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment, ExampleFragment.TAG).commit();

请注意,在您的情况下,应该使用Fragment.TAG,但我使用ExampleFragment来澄清Fragment.TAG不是Android SDK的一部分。
要在活动中获取片段的引用,请使用FragmentManager查找您的片段:
Fragment myFragment = getSupportFragmentManager().findFragmentByTag(ExampleFragment.TAG);

然后,您可以确保myFragment不为null并将其转换为FragmentCommunicator

if (myFragment != null) {
    fragmentCommunicator = (FragmentCommunicator) myFragment;
}

请注意,在您的示例中,fragmentCommunicator = (FragmentCommunicator) getApplication(); 是无效的,因为实现接口的是您的片段,而不是您的应用程序。

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