361

试图从片段中调用我的活动中的方法。我希望片段提供方法数据并在方法返回时获取数据。我想实现类似于调用静态方法,但不使用静态,因为它会在活动中产生问题。

片段新手,所以我需要一个简单而有教学意义的解释!

谢谢!

4

17 回答 17

909

从片段到活动:

((YourActivityClassName)getActivity()).yourPublicMethod();

从活动到片段:

FragmentManager fm = getSupportFragmentManager();

//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();

如果您通过代码添加片段并在添加片段tag时使用了字符串,请findFragmentByTag改用:

YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");
于 2012-09-30T08:23:29.280 回答
221

您可能应该尝试将片段与活动分离,以防您想在其他地方使用它。您可以通过创建您的活动实现的接口来做到这一点。

因此,您将定义一个如下所示的接口:

例如,假设您想给活动一个字符串并让它返回一个整数:

public interface MyStringListener{
    public Integer computeSomething(String myString);
}

这可以在片段或单独的文件中定义。

然后你会让你的活动实现接口。

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

}

然后在您的片段中,您将有一个 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. */
            }
        }

    }

编辑(17.12.2015):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended

第一个答案肯定有效,但它将您当前的片段与主机活动相结合。如果您想在另一个活动中使用它,将片段与主机活动分离,这是一种很好的做法。

于 2012-10-02T02:05:40.827 回答
88

对于Kotlin开发人员

(activity as YourActivityClassName).methodName()

对于Java开发人员

((YourActivityClassName) getActivity()).methodName();
于 2018-03-14T08:57:42.273 回答
16

在我了解更多片段如何工作后更新。每个片段都属于一个父活动。所以只需使用:

getActivity().whatever

从片段内部。这是一个更好的答案,因为您避免了多余的演员表。如果您无法使用此解决方案避免演员阵容,请使用以下解决方案。

=============

你要做的就是投射到外部活动

((MainActivity) getActivity()).Method();

创建一个新实例会混淆 android 框架并且它无法识别它。也可以看看 :

https://stackoverflow.com/a/12014834/1984636

https://stackoverflow.com/a/2042829/1984636

于 2015-03-04T15:01:49.783 回答
9

虽然我完全喜欢 Marco 的回答,但我认为公平地指出,您也可以使用基于发布/订阅的框架来实现相同的结果,例如,如果您使用事件总线,您可以执行以下操作

片段:

EventBus.getDefault().post(new DoSomeActionEvent()); 

活动:

 @Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something

}
于 2016-05-11T11:00:35.260 回答
6

在 kotlin 中,您可以从片段中调用活动方法,如下所示:

var mainActivity: MainActivity = activity as MainActivity
        mainActivity.showToast() //Calling show toast method of activity
于 2018-05-31T07:45:02.660 回答
4

感谢@BIJAY_JHA 和@Manaus。我使用 Kotlin 版本来调用我的 signIn() 方法,该方法位于 Activity 中并且我从 Fragment 调用。我在 Android 中使用导航架构,因此侦听器接口模式不在片段中:

 (activity as MainActivity).signIn() 
于 2020-07-15T09:19:00.010 回答
4

我是这样做的:

首先制作界面

interface NavigationInterface {
    fun closeActivity()
}

接下来确保活动实现接口并覆盖接口方法

class NotesActivity : AppCompatActivity(), NavigationInterface {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notes)
        setSupportActionBar(findViewById(R.id.toolbar))
    }

    override fun closeActivity() {
        this.finish()
    }
}

然后确保在片段中创建接口侦听器

private lateinit var navigationInterface: NavigationInterface

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
): View? {
    //establish interface communication
    activity?.let {
        instantiateNavigationInterface(it)
    }
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_notes_info, container, false)
}

private fun instantiateNavigationInterface(context: FragmentActivity) {
    navigationInterface = context as NavigationInterface
}

那么你可以像这样拨打电话:

view.findViewById<Button>(R.id.button_second).setOnClickListener {
    navigationInterface.closeActivity()
}
于 2021-01-05T19:08:43.233 回答
3

要通过片段访问 Activity 中声明的函数,请使用接口,如 marco 的回答所示。

要通过您的活动访问片段中声明的函数,如果您没有标签或 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


}

这是 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);
    }
}

这个答案适合我这样的菜鸟。祝你有美好的一天。

于 2016-08-26T08:05:38.610 回答
2

这是来自片段类...

((KidsStoryDashboard)getActivity()).values(title_txt,bannerImgUrl);

活动类中的此代码...

 public void values(String title_txts, String bannerImgUrl) {
    if (!title_txts.isEmpty()) {

//Do something to set text 
    }
    imageLoader.displayImage(bannerImgUrl, htab_header_image, doption);
}
于 2016-08-18T12:14:45.647 回答
1

我一直在寻找最好的方法来做到这一点,因为并非我们要调用的每个方法都位于具有相同 Activity Parent 的 Fragment 中。

在你的片段中

public void methodExemple(View view){

        // your code here

        Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
    }

在您的活动中

new ExempleFragment().methodExemple(context); 
于 2018-06-09T00:02:35.390 回答
1

我已经尝试了这个线程中显示的所有方法,但没有一个对我有用,试试这个。它对我有用。

((MainActivity) getContext().getApplicationContext()).Method();
于 2019-05-17T13:13:51.090 回答
1
((your_activity) getActivity).method_name()

whereyour_activity是您的活动method_name()的名称,是您要调用的方法的名称。

于 2019-09-26T14:44:53.503 回答
1

对于 Kotlin 试试看

class DataForm : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Tasks(this).getData()
    }

    fun getResponse(response: String) {
        // code
    }
}

class Tasks(private val context: Any) {
    fun getData() {

        val getContext = (context as DataForm).activity
        val getFragment = (context as DataForm)

        val responseListener = Response.Listener<String> { response ->
            getFragment.getResponse(response)
        }

        val errorListener = Response.ErrorListener { error ->
            error.printStackTrace();
        }

        val stringRequest = StringRequest(Request.Method.GET, url, responseListener, errorListener)
        Volley.newRequestQueue(getContext).add(stringRequest)
    }
}
于 2020-02-24T07:51:29.620 回答
0

((YourActivityName)getActivity()).functionName();

例子 :((SessionActivity)getActivity()).changeFragment();

注意:类名应该是公开的

于 2019-01-28T08:03:37.243 回答
0

从片段到活动:

((YourActivityClassName)requireActivity()).yourPublicMethod();

于 2021-08-28T06:33:14.907 回答
-1

从各自的片段调用活动方法的最佳方式

(activity as YourActivity).activtiyMethod()

从你的活动中使用这条线。例如

Suppose You have Activity A and method add() and your fragment ABC and you want to call the method add from Fragment ABC,

(activity as A).add()
于 2022-01-31T14:00:18.807 回答