Android 从片段调用活动方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12659747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Call an activity method from a fragment
提问by Joakim Ericsson
Trying to call a method in my activity from a fragment. I want the fragment to give the method data and to get the data when the method return. I want to achieve similar to call on a static method, but without the use of static because it create problems in the activity.
试图从片段中调用我的活动中的方法。我希望片段提供方法数据并在方法返回时获取数据。我想实现类似于对静态方法的调用,但不使用静态方法,因为它会在活动中产生问题。
New to fragments so I need an easy and pedagogic explanation!
片段的新手,所以我需要一个简单的教学解释!
Thanks!
谢谢!
回答by Richard
From fragment to activty:
从片段到活动:
((YourActivityClassName)getActivity()).yourPublicMethod();
From activity to fragment:
从活动到片段:
FragmentManager fm = getSupportFragmentManager();
//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();
If you added fragment via code and used a tag
string when you added your fragment, use findFragmentByTag
instead:
如果您通过代码添加了片段并tag
在添加片段时使用了字符串,请findFragmentByTag
改用:
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");
回答by Marco RS
You should probably try to decouple the fragment from the activity in case you want to use it somewhere else. You can do this by creating a interface that your activity implements.
如果您想在其他地方使用它,您可能应该尝试将片段与活动分离。您可以通过创建您的 Activity 实现的接口来实现此目的。
So you would define an interface like the following:
因此,您将定义一个如下所示的接口:
Suppose for example you wanted to give the activity a String and have it return a Integer:
例如,假设您想为活动提供一个字符串并让它返回一个整数:
public interface MyStringListener{
public Integer computeSomething(String myString);
}
This can be defined in the fragment or a separate file.
这可以在片段或单独的文件中定义。
Then you would have your activity implement the interface.
然后你会让你的活动实现接口。
public class MyActivity extends FragmentActivity implements MyStringListener{
@Override
public Integer computeSomething(String myString){
/** Do something with the string and return your Integer instead of 0 **/
return 0;
}
}
Then in your fragment you would have a MyStringListener variable and you would set the listener in fragment onAttach(Activity activity) method.
然后在您的片段中,您将有一个 MyStringListener 变量,您将在片段 onAttach(Activity activity) 方法中设置侦听器。
public class MyFragment {
private MyStringListener listener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (MyStringListener) context;
} catch (ClassCastException castException) {
/** The activity does not implement the listener. */
}
}
}
edit(17.12.2015):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended
编辑(17.12.2015):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended
The first answer definitely works but it couples your current fragment with the host activity. Its good practice to keep the fragment decoupled from the host activity in case you want to use it in another acitivity.
第一个答案肯定有效,但它将您当前的片段与主机活动结合起来。如果您想在另一个活动中使用它,最好将片段与宿主活动分离。
回答by Wasim K. Memon
For Kotlindevelopers
对于Kotlin开发人员
(activity as YourActivityClassName).methodName()
For Javadevelopers
对于Java开发人员
((YourActivityClassName) getActivity()).methodName();
回答by sivi
Update after I understand more how fragments work. Each fragment belongs to a parent activity. So just use:
在我了解更多片段如何工作后更新。每个片段都属于一个父活动。所以只需使用:
getActivity().whatever
From within the fragment. It is a better answer because you avoid superflous casts. If you cannot avoid the casts with this solution use the one below.
从片段内。这是一个更好的答案,因为您避免了多余的演员表。如果您无法避免使用此解决方案进行强制转换,请使用以下解决方案。
============
============
what you have to do is to cast to the outer activity
你要做的就是投射到外部活动
((MainActivity) getActivity()).Method();
creating a new instance will be confusing the android frame and it will not be able to recognize it. see also :
创建一个新实例会混淆 android 框架并且它无法识别它。也可以看看 :
https://stackoverflow.com/a/12014834/1984636
https://stackoverflow.com/a/12014834/1984636
回答by A.Alqadomi
Although i completely like Marco's Answer i think it is fair to point out that you can also use a publish/subscribe based framework to achieve the same result for example if you go with the event bus you can do the following
虽然我完全喜欢 Marco 的答案,但我认为可以公平地指出,您也可以使用基于发布/订阅的框架来实现相同的结果,例如,如果您使用事件总线,您可以执行以下操作
fragment :
片段:
EventBus.getDefault().post(new DoSomeActionEvent());
Activity:
活动:
@Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something
}
回答by Maya Mohite
In kotlin you can call activity method from fragment like below:
在 kotlin 中,您可以从片段中调用活动方法,如下所示:
var mainActivity: MainActivity = activity as MainActivity
mainActivity.showToast() //Calling show toast method of activity
回答by hispeed
For accessing a function declared in your Activity via your fragment please use an interface, as shown in the answer by marco.
要通过片段访问活动中声明的函数,请使用接口,如 marco 的回答所示。
For accessing a function declared in your Fragment via your activity you can use this if you don't have a tag or an id
要通过您的活动访问 Fragment 中声明的函数,如果您没有标签或 ID,则可以使用它
private void setupViewPager(ViewPager viewPager) {
//fragmentOne,fragmentTwo and fragmentThree are all global variables
fragmentOne= new FragmentOne();
fragmentTwo= new FragmentTwo();
fragmentThree = new FragmentThree();
viewPagerAdapteradapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapteradapter.addFragment(fragmentOne, "Frag1");
viewPagerAdapteradapter.addFragment(fragmentTwo, "Frag2");
viewPagerAdapteradapter.addFragment(fragmentThree, "Frag3");
//viewPager has to be instantiated when you create the activity:
//ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
//setupViewPager(viewPager);
//Where R.id.pager is the id of the viewPager defined in your activity's xml page.
viewPager.setAdapter(viewPagerAdapteradapter);
//frag1 and frag2 are also global variables
frag1 = (FragmentOne)viewPagerAdapteradapter.mFragmentList.get(0);
frag2 = (FragmentTwo)viewPagerAdapteradapter.mFragmentList.get(1);;
//You can use the variable fragmentOne or frag1 to access functions declared in FragmentOne
}
This is the ViewpagerAdapterClass
这是 ViewpagerAdapterClass
class ViewPagerAdapter extends FragmentPagerAdapter {
public final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
This answer is for noobs like me. Have a good day.
这个答案适用于像我这样的菜鸟。祝你有美好的一天。
回答by Sergio Velásquez
I have tried with all the methods shown in this thread and none worked for me, try this one. It worked for me.
我已经尝试了这个线程中显示的所有方法,但没有一个对我有用,试试这个。它对我有用。
((MainActivity) getContext().getApplicationContext()).Method();
回答by Mathan Chinna
This is From Fragment class...
这是从片段类...
((KidsStoryDashboard)getActivity()).values(title_txt,bannerImgUrl);
This Code From Activity Class...
此代码来自活动类...
public void values(String title_txts, String bannerImgUrl) {
if (!title_txts.isEmpty()) {
//Do something to set text
}
imageLoader.displayImage(bannerImgUrl, htab_header_image, doption);
}
回答by Maravilho Singa
I have been looking for the best way to do that since not every method we want to call is located in Fragment with same Activity Parent.
我一直在寻找最好的方法来做到这一点,因为并非我们想要调用的每个方法都位于具有相同 Activity Parent 的 Fragment 中。
In your Fragment
在你的片段中
public void methodExemple(View view){
// your code here
Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
}
In your Activity
在您的活动中
new ExempleFragment().methodExemple(context);