如何实现OnFragmentInteractionListener

我有一个向导生成的应用程序与导航抽屉在Android Studio 0.8.2

我创建了一个片段,并添加newInstance(),我得到这个错误:

  com.domain.myapp E / AndroidRuntime:致命例外:主
     java.lang.ClassCastException: 
 com.domain.myapp.MainActivity@422fb8f0 
必须实现OnFragmentInteractionListener 

我无法找到任何地方如何实现这个OnFragmentInteractionListener? 即使在android sdk文档中也找不到它!

MainActivity.java

import android.app.Activity; import android.app.ActionBar; import android.app.Fragment; import android.app.FragmentManager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.support.v4.widget.DrawerLayout; public class MainActivity extends Activity implements NavigationDrawerFragment.NavigationDrawerCallbacks { /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. */ private NavigationDrawerFragment mNavigationDrawerFragment; /** * Used to store the last screen title. For use in {@link #restoreActionBar()}. */ private CharSequence mTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager().findFragmentById(R.id.navigation_drawer); mTitle = getTitle(); // Set up the drawer. mNavigationDrawerFragment.setUp( R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout)); } @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getFragmentManager(); switch (position) { case 0: fragmentManager.beginTransaction() .replace(R.id.container, PlaceholderFragment.newInstance(position + 1)) .commit(); break; case 1: fragmentManager.beginTransaction() .replace(R.id.container, AboutFragment.newInstance("test1", "test2")) .commit(); break; // this crashes the app case 2: fragmentManager.beginTransaction() .replace(R.id.container, BrowseQuotesFragment.newInstance("test1", "test2")) .commit(); break; // this crashes the app } } public void onSectionAttached(int number) { switch (number) { case 1: mTitle = getString(R.string.title_section1); break; case 2: mTitle = getString(R.string.title_section2); break; case 3: mTitle = getString(R.string.title_section3); break; } } public void restoreActionBar() { ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle(mTitle); } @Override public boolean onCreateOptionsMenu(Menu menu) { if (!mNavigationDrawerFragment.isDrawerOpen()) { // Only show items in the action bar relevant to this screen // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. getMenuInflater().inflate(R.menu.main, menu); restoreActionBar(); return true; } return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ private static final String ARG_SECTION_NUMBER = "section_number"; /** * Returns a new instance of this fragment for the given section * number. */ public static PlaceholderFragment newInstance(int sectionNumber) { PlaceholderFragment fragment = new PlaceholderFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } @Override public void onAttach(Activity activity) { super.onAttach(activity); ((MainActivity) activity).onSectionAttached( getArguments().getInt(ARG_SECTION_NUMBER)); } } 

}

这里发布的答案没有帮助,但下面的链接做了:

http://developer.android.com/training/basics/fragments/communicating.html

定义一个接口

 public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // Container Activity must implement this interface public interface OnHeadlineSelectedListener { public void onArticleSelected(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 = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } } ... } 

例如,在用户点击一个列表项时调用片段中的以下方法。 该片段使用回调接口将事件传递给父活动。

 @Override public void onListItemClick(ListView l, View v, int position, long id) { // Send the event to the host activity mCallback.onArticleSelected(position); } 

实现接口

例如,以下活动将实现上述示例中的界面。

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

更新API 23:8/31/2015

onAttach(Activity activity)重写方法现在在android.app.Fragment被弃用了,代码应该被升级到onAttach(Context context)

 @Override public void onAttach(Context context) { super.onAttach(context); } @Override public void onStart() { super.onStart(); try { mListener = (OnFragmentInteractionListener) getActivity(); } catch (ClassCastException e) { throw new ClassCastException(getActivity().toString() + " must implement OnFragmentInteractionListener"); } } 

对于那些读完@meda回答后仍然不明白的人,下面是我对这个问题的简明扼要的解释:

假设您有2个Fragment, Fragment_AFragment_B ,它们是从应用程序自动生成的。 在你生成的片段的底部,你会找到这个代码:

 public class Fragment_A extends Fragment { //rest of the code is omitted public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } } public class Fragment_B extends Fragment { //rest of the code is omitted public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } } 

为了克服这个问题,你必须在你的活动中添加onFragmentInteraction方法,在我的情况下,这个方法被命名为MainActivity2 。 之后,您需要像这样在MainActivity实现所有片段:

 public class MainActivity2 extends ActionBarActivity implements Fragment_A.OnFragmentInteractionListener, Fragment_B.OnFragmentInteractionListener, NavigationDrawerFragment.NavigationDrawerCallbacks { //rest code is omitted @Override public void onFragmentInteraction(Uri uri){ //you can leave it empty } } 

PS:总之,这个方法可以用来在片段之间进行通信。 对于那些想了解这种方法的人,请参考这个链接 。

查看由Android Studio创建的自动生成的Fragment 。 当你创建新的Fragment ,Studio会为你留下一堆代码。 在自动生成的模板的底部有一个名为OnFragmentInteractionListener的内部接口定义。 你的Activity需要实现这个接口。 这是你的Fragment通知你的Activity事件的建议模式,以便它可以采取适当的行动,比如加载另一个Fragment 。 有关详细信息,请参阅此页面,查找“为活动创建事件回调”部分: http : //developer.android.com/guide/components/fragments.html

对于那些访问这个页面的人来说,这个错误需要进一步澄清,在我的情况下,在这种情况下,调用碎片需要有2个工具,如下所示:

 public class MyActivity extends Activity implements MyFragment.OnFragmentInteractionListener, NavigationDrawerFragment.NaviationDrawerCallbacks { ...// rest of the code } 

您应该尝试从您的片段中删除以下代码

  try { mListener = (OnFragmentInteractionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener"); } 

接口/侦听器是一个默认的创建,以便您的活动和片段可以更容易沟通

除了@ user26409021的回答,如果你已经添加了一个ItemFragment,ItemFragment中的消息是;

 Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener} interface. 

而你应该加入你的活动;

 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, ItemFragment.OnListFragmentInteractionListener { //the code is omitted public void onListFragmentInteraction(DummyContent.DummyItem uri){ //you can leave it empty } 

这里的虚拟物品是你的ItemFragment的底部

而不是活动使用上下文。它适用于我。

 @Override public void onAttach(Context context) { super.onAttach(context); try { mListener = (OnFragmentInteractionListener) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString() + " must implement OnFragmentInteractionListener"); } } 

只是一个附录:

OnFragmentInteractionListener使用接口 (OnFragmentInteractionListener) 处理Activity和Fragment之间的通信,并且是由Android Studio默认创建的,但是如果您不需要与您的活动进行通信,则可以使用它。

目标是你可以将你的片段附加到多个活动,并仍然重复使用相同的通信方法 (每个活动可以有自己的OnFragmentInteractionListener为每个片段)。

但是,如果我确定我的片段将只附加到一种类型的活动,我想与该活动沟通?

然后,如果由于冗长而不想使用OnFragmentInteractionListener,则可以使用以下命令访问您的活动方法:

 ((MyActivityClass) getActivity()).someMethod() 

我想添加碎片从活动分离或销毁时的监听器的销毁。

 @Override public void onDetach() { super.onDetach(); mListener = null; } 

并在Context中使用新的onStart()方法时

 @Override public void onDestroy() { super.onDestroy(); mListener = null; }