I'm having problems with the viewPager I'm trying to add to my application.
I have a SearchResultActivity in which there is a box. with the following location:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#111" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" />
because I use fragments, when I first get this action, I open a transaction to open the RecipeHeadlinesFragment in the Activity onCreate method:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.drawer_main); mSearchType = getIntent().getIntExtra(SEARCH_TYPE, -1); if (mSearchType == ICON_SEARCH) { mVeggieNamesIcons = getIntent().getStringArrayListExtra( VEGGIE_NAME_ARR); mVeggieUrlsIcons = getIntent().getStringArrayListExtra( VEGGIE_URLS_ARR); } else if (mSearchType == QUERY_SEARCH) { mQuery = getIntent().getStringExtra(QUERY); } // Generate title title = new String[] { "Search for a recipe", "My profile", "Title Fragment 3" }; // Generate subtitle subtitle = new String[] { "", "", "Subtitle Fragment 3" }; // Generate icon icon = new int[] { R.drawable.action_about, R.drawable.action_settings, R.drawable.collections_cloud }; // Locate DrawerLayout in drawer_main.xml mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // Locate ListView in drawer_main.xml mDrawerList = (ListView) findViewById(R.id.left_drawer); // Set a custom shadow that overlays the main content when the drawer // opens mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // Pass results to MenuListAdapter Class mMenuAdapter = new MenuListAdapter(this, title, subtitle, icon); // Set the MenuListAdapter to the ListView mDrawerList.setAdapter(mMenuAdapter); // Capture button clicks on side menu mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); // Enable ActionBar app icon to behave as action to toggle nav drawer getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); // ActionBarDrawerToggle ties together the the proper interactions // between the sliding drawer and the action bar app icon mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.menubutton, R.string.drawer_open, R.string.drawer_close) { public void onDrawerClosed(View view) { getActionBar().setTitle(""); // getActionBar().setBackgroundDrawable(d) super.onDrawerClosed(view); invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle("menu"); // getActionBar().setBackgroundDrawable(new // ColorDrawable(Color.GREEN)); super.onDrawerOpened(drawerView); invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); // Check whether the activity is using the layout version with // the fragment_container FrameLayout. If so, we must add the first // fragment if (findViewById(R.id.content_frame) != null) { if (savedInstanceState == null) { Bundle args = new Bundle(); args.putInt(SEARCH_TYPE, mSearchType); if (mSearchType == QUERY_SEARCH) { args.putString(QUERY, mQuery); } else if (mSearchType == ICON_SEARCH) { args.putStringArrayList(VEGGIE_NAME_ARR, mVeggieNamesIcons); args.putStringArrayList(VEGGIE_URLS_ARR, mVeggieUrlsIcons); } recipeHeadlines.setArguments(args); // Add the fragment to the 'fragment_container' FrameLayout FragmentTransaction ft = getSupportFragmentManager() .beginTransaction().replace(R.id.content_frame, recipeHeadlines); ft.commit(); } else { return; } } getActionBar().setIcon(R.color.transparent); }
The HeadlinesFragment recipe is a sherlockListFragment. I created the onArticleSelectedListener interface in it and made it implement, so when the list item is selected, the onArticleSelected action is called, and the RecipeTabsFragment is triggered and passed to the front using another transaction:
public void onArticleSelected(int position, RecipeObj obj) {
this is my RecipeTabsFragment code:
public class RecipeTabsFragment extends SherlockFragment { // Declare Variables final static String ARG_POSITION = "position"; final static String TAB_POSITION = "tab"; final static String ARG_RECIPE = "recipeData"; View rootView; ActionBar mActionBar; TextView mRecipeTitle; TextView mRecipeBloger; RatingBar mRecipeRatingBar; int mCurrentPosition = -1; int mCurrentTab = 0; static ViewPager mPager; Tab tab; FragmentStatePagerAdapter mAdapter; static final int NUM_ITEMS = 3; // View rootView; EditText editsearch; ProgressDialog mProgressDialog; // ImageAndName[] mTemplist = {}; GridView gridview; private RecipeObj mRecipeData; // The container Activity must implement this interface so the frag can // deliver messages public interface OnNameSetter { /** Called by HeadlinesFragment when a list item is selected */ public void setName(String name); public String getName(); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onPrepareOptionsMenu(Menu menu) { //initialize the recipe title,bloger and rating view on the action bar MenuItem item = menu.findItem(R.id.data_item); mRecipeTitle = (TextView) item.getActionView().findViewById( R.id.tv_title_ab); mRecipeBloger = (TextView) item.getActionView().findViewById( R.id.tv_bloger_ab); mRecipeRatingBar = (RatingBar) item.getActionView().findViewById( R.id.rb_list_item_ab); //set the actual data to the view mRecipeTitle.setText(mRecipeData.getFields().getName()); super.onPrepareOptionsMenu(menu); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.recip_detail, menu); super.onCreateOptionsMenu(menu, inflater); } @SuppressWarnings("null") @Override public void onStart() { super.onStart(); Bundle args = getArguments(); if (args != null) { // Set article based on argument passed in updateArticleView(args.getInt(ARG_POSITION), (RecipeObj) args.getParcelable(ARG_RECIPE)); } else if (mCurrentPosition != -1) { // Set article based on saved instance state defined during // onCreateView updateArticleView(mCurrentPosition, mRecipeData); } } public void updateArticleView(int position, RecipeObj data) { mRecipeData = data; mCurrentPosition = position; } public void onResume() { super.onResume(); //allows to put data on action bar that is not a action widget getSherlockActivity().supportInvalidateOptionsMenu(); mActionBar = getSherlockActivity().getSupportActionBar(); mActionBar.setTitle(""); FragmentManager fm = getSherlockActivity().getSupportFragmentManager(); final ArrayList<String> titles = new ArrayList<String>(); titles.add("tab1"); titles.add("tab2"); titles.add("tab3"); mAdapter = new FragmentStatePagerAdapter(fm){ @Override public Fragment getItem(int position) { switch (position) { case 0: // Your current main fragment showing how to send arguments to // fragment RecipeArticle fragment1 = new RecipeArticle(); Bundle data1 = new Bundle(); data1.putParcelable(RecipeTabsFragment.ARG_RECIPE, mRecipeData); fragment1.setArguments(data1); fragment1.setName(titles.get(position)); return fragment1; case 1: // Calling a Fragment without sending arguments RecipePreparation fragment2 = new RecipePreparation(); Bundle data2 = new Bundle(); data2.putParcelable(RecipeTabsFragment.ARG_RECIPE, mRecipeData); fragment2.setArguments(data2); fragment2.setName(titles.get(position)); return fragment2; case 2: Fragments3 fragment3 = new Fragments3(); // Bundle data2 = new Bundle(); // data2.putParcelable(IngrFragment.ARG_RECIPE, recipeData); // fragment2.setArguments(data2); fragment3.setName(titles.get(position)); return fragment3; default: return null; } } @Override public int getCount() { // TODO Auto-generated method stub return NUM_ITEMS; } @Override public int getItemPosition(Object item) { OnNameSetter fragment = (OnNameSetter)item; String title = fragment.getName(); int position = titles.indexOf(title); if (position >= 0) { return position; } else { return POSITION_NONE; } } }; mPager = (ViewPager) rootView.findViewById(R.id.pager); mPager.setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); mPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } // // @Override public void onPageSelected(int arg0) { mActionBar.getTabAt(arg0).select(); } }); mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Create first Tab tab = mActionBar .newTab() .setText(getString(string.ingrdients)) .setTabListener( new TabListener<RecipeArticle>(this .getSherlockActivity(), "SearchPage1", RecipeArticle.class)); tab.setIcon(R.drawable.ing); mActionBar.addTab(tab); // Create second Tab tab = mActionBar .newTab() .setText(getString(string.prepration)) .setTabListener( new TabListener<RecipePreparation>(this .getSherlockActivity(), "SearchPage2", RecipePreparation.class)); tab.setIcon(R.drawable.how); mActionBar.addTab(tab); // Create third Tab tab = mActionBar .newTab() .setText(getString(string.comments)) .setTabListener( new TabListener<Fragments3>(this.getSherlockActivity(), "SearchPage3", Fragments3.class)); tab.setIcon(R.drawable.why); mActionBar.addTab(tab); setHasOptionsMenu(true); mActionBar.getTabAt(mCurrentTab).select(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (savedInstanceState != null) { mCurrentPosition = savedInstanceState.getInt(ARG_POSITION); mRecipeData = savedInstanceState.getParcelable(ARG_RECIPE); mCurrentTab = savedInstanceState.getInt(TAB_POSITION); } rootView = inflater.inflate(R.layout.ingr_tabs, container, false); return rootView; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save the current article selection in case we need to recreate the // fragment outState.putInt(ARG_POSITION, mCurrentPosition); outState.putInt(TAB_POSITION, mCurrentTab); outState.putParcelable(ARG_RECIPE, mRecipeData); } public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final SherlockFragmentActivity mActivity; private final String mTag; private final Class<T> mClass; /** * Constructor used each time a new tab is created. * * @param sherlockFragmentActivity * The host Activity, used to instantiate the fragment * @param tag * The identifier tag for the fragment * @param clz * The fragment Class, used to instantiate the fragment */ public TabListener(SherlockFragmentActivity sherlockFragmentActivity, String tag, Class<T> clz) { mActivity = sherlockFragmentActivity; mTag = tag; mClass = clz; } /* The following are each of the ActionBar.TabListener callbacks */ public void onTabSelected(Tab tab, FragmentTransaction ft) { mPager.setCurrentItem(tab.getPosition()); } public void onTabUnselected(Tab tab, FragmentTransaction ft) { } public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } }
}
and this is the RecipeTabsFragment layout, ingr_tabs.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:tag="ingr_screen" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="fill_parent" android:layout_height="wrap_content" > </android.support.v4.view.ViewPager>
Now, for some reason, being in the RecipeTabsFragment and temporarily leaving the application (exiting the main menu or the device goes into sleep mode) and returning to the application, the application crashes and the following exception occurs:
#
Does anyone know what happened? the other thing that happens and can be connected is that, being in the RecipeTabsFragment and clicking on the back button, I return to the main action of my application and not to the RecipeHeadlinesFragment, although the actual place where I was before the RecipeTabsFragment. Help someone? EDIT : Therefore, I think I found the cause of the main problem that I asked about ... when I was terrified, I called getSherlockActivity () to get the FragmentManager instead of calling the getChildFragmentManager () fragment. the problem is resolved.