Trouble with ViewPager displaying Fragments - android

I am trying to get a fragment with three tabs displayed using ViewPager. Initially I used to instantiate the fragment from the Activity using FragmentMgr, this worked fine. When I converted this navigation using ViewPager, this Fragment is no longer displayed.
MainActivity.java
When I initiate Fragment like this, it gets displayed. eg:
LaunchListFragment fragment = new LaunchListFragment();
fragment.newInstance(LIST_TYPE);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container,
fragment).commit();
I tried this change above code to make use of ViewPager as follows:
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(new LaunchPageAdapter(getSupportFragmentManager(),LIST_TYPE));
mViewPager.setCurrentItem(0);
where LaunchPageAdapter calls LaunchListFragment.
LaunchPageAdapter.java
public class LaunchPageAdapter extends FragmentPagerAdapter {
private static String select="";
public LaunchPageAdapter(FragmentManager fm, String type) {
super(fm);
select=type;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return LaunchListFragment.newInstance(select);
case 1:
return AddTeamFragment.newInstance();
}
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 2;
}
Here is LaunchListFragment.java
public class LaunchListFragment extends ListFragment implements ActionBar.TabListener {
public static String LIST_TYPE = "invalid";
GenericListData g_data[] = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_launch_list,
container, false);
setActionTabs();
setList();
return (result);
}
public static Fragment newInstance(String type) {
Fragment frag = new LaunchListFragment();
Bundle args = new Bundle();
LIST_TYPE=type;
args.putString(LIST_TYPE, type);
frag.setArguments(args);
return (frag);
}
This is main.xml layout used by MainActivity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools= "match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".MainActivity" >
<fragment
android:id="#+id/item_list"
android:name="com.teammanager.ItemListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#android:layout/list_content" />
<FrameLayout
android:id="#+id/item_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</FrameLayout>
fragment_launch_list.xml used by LaunchListFragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false" >
</ListView>
<TextView
android:id="#+id/itemName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:textColor="#000000"
android:textSize="22dp"
android:textStyle="bold" />
When I debug this, I can see LaunchListFragment is getting instantiated, onCreate and onCreate View is called, it just won't get displayed. :(
Can anyone here let me know if I am missing anything here in my ViewPager implementation?
Update
When I called LaunchListFragment without using Viewpager, I set the content view first and passed R.id.item_detail_container which is the id of the FrameLayout where I want the fragment to be displayed. Please refer to main.xml earlier
setContentView(R.layout.main.xml);
LaunchListFragment fragment = new LaunchListFragment();
fragment.newInstance(LIST_TYPE);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container,
fragment).commit();
When I changed this to use ViewPager, I am not sure where I'm directing the Fragment to be displayed. In my fragment onView I'm inflating fragment_launch_list and returning the View. But how will the view pager know where to set the fragment view. Is it inside the id pager?
I'm an absolute beginner, I apologize if all these are naive questions.
Cheers.

The question description is perfectly suitable to the problem I just had. I know the question is old but may this help other who face same. #Geoplex have not shown code of LaunchPageAdapter class. So I'm not sure if this solves his problem or not. But for me that worked.
In my PagerAdapter, the
public boolean isViewFromObject(View view, Object object) was overridden. I removed that method and allowed superClass to handle it. That started giving my expected result.

This is useful for you,
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments=null;
private FragmentManager fragmentManager=null;
public ViewPagerAdapter(FragmentManager fragmentManager,List<Fragment> fragments) {
super(fragmentManager);
this.fragments=fragments;
this.fragmentManager=fragmentManager;
}
#Override
public Fragment getItem(int position) {
fragmentManager.beginTransaction().commitAllowingStateLoss();
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
{
super.setPrimaryItem(container,0,fragments.get(0));
}
#Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
fragmentManager.executePendingTransactions();
fragmentManager.saveFragmentInstanceState(fragments.get(position));
}
public void replaceItem(int position,Fragment fragment)
{
fragments.set(position, fragment);
this.notifyDataSetChanged();
}
}
MainActivity.java
public class MainActivity extends FragmentActivity implements OnPageChangeListener,TabListener
{
private android.support.v4.view.ViewPager mViewPager=null;
private ViewPagerAdapter mPagerAdapter=null;
private ActionBar action=null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
initilizeViewPager();
action=getActionBar();
action.setDisplayShowHomeEnabled(false);
action.setDisplayShowTitleEnabled(false);
action.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
public void initilizeViewPager()
{
mViewPager=(android.support.v4.view.ViewPager)findViewById(R.id.viewPager);
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(LaunchListFragment.newInstance(select));
fragments.add(AddTeamFragment.newInstance());
fragments.add(thirdFragment.newInstance());
viewPagerAdapter=new ViewPagerAdapter();
mViewPager.setAdapter(viewPagerAdapter(getSupportFragmentManager(),fragments));
new setAdapterTask().execute();
mViewPager.setOnPageChangeListener(this);
}
private class setAdapterTask extends AsyncTask<Void,Void,Void>
{
protected Void doInBackground(Void... params)
{
return null;
}
#Override
protected void onPostExecute(Void result)
{
mViewPager.setAdapter(mPagerAdapter);
Tab first=action.newTab().setTag("first").setText("First").setTabListener(MainActivity.this);
Tab second=action.newTab().setTag("second").setText("Second").setTabListener(MainActivity.this);
Tab third=action.newTab().setTag("third").setText("Third").setTabListener(MainActivity.this);
action.addTab(first);
action.addTab(second);
action.addTab(third);
}
}
}
public void onPageScrollStateChanged(int arg0)
{}
public void onPageScrolled(int arg0, float arg1, int arg2)
{}
public void onPageSelected(int position)
{
getActionBar().setSelectedNavigationItem(position);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
}
main_layout.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_below="#android:id/tabs"
android:layout_height="fill_parent"/>
</RelativeLayout>

Related

ViewPage Fragment disappear when reload again

The following is layout
test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Click"
android:id="#+id/button"
/>
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
test_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hello"
android:id="#+id/textView" android:layout_gravity="center_horizontal"/>
</LinearLayout>
common_view_pager_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/MainViewerPage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.PagerTabStrip
android:id="#+id/TitlePageTabStrip"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.view.ViewPager>
</LinearLayout>
The following is my Activity code
public class TestFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.test);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, new HomeFragment()).commit();
}
});
}
public class HomeFragment extends Fragment {
private PagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
this._adapter = new PagerAdapter(TestFragmentActivity.this);
this._adapter.add(new DetailFragment());
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
pager.setAdapter(this._adapter);
return view;
}
}
public class DetailFragment extends Fragment {
public DetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.test_detail, container, false);
return rootView;
}
}
public class PagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public PagerAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
}
When I click a button the fragment in ViewPager was display
But when I click the button again the fragment disappear
Please help me.
try using this:
in the constructor of your adapter change this :
public class MyPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public MyPagerAdapter(FragmentManager activity) {
super(activity);
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
and when you want to create the adapter send getChildFragmentManager() to its constructor
public class HomeFragment extends Fragment {
private MyPagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
this._adapter = new MyPagerAdapter(getChildFragmentManager());
this._adapter.add(new DetailFragment());
pager.setAdapter(this._adapter);
return view;
}
}
I test it and it works, any problem comment it.
Good Luck!
In your Fragment class, in the onCreate() method, you have to call setRetainInstance(true) like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
This tells the FragmentManager to keep your fragments on reloads.
In addition, check your manifest file doesn't have any
android:screenOrientation
config changes where you are basically saying you will handle reloads due to config changes yourself.
In PagerFragment 's onResume() add this:
#Override
public void onResume() {
super.onResume();
for (Fragment fragment : getFragmentManager().getFragments()) {
if (fragment instanceof Tab1Fragment || fragment instanceof Tab2Fragment) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(fragment);
ft.attach(fragment);
ft.commit();
}
}
}
Try to add this lines in your code:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
and Add the below lines
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
... anything you may need to do to handle pager state ...
adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
}
Under
pager.setAdapter(adapter);
Hope this may help you!
Ensure you pass the adapter instance the child fragment manager, not the fragment manager.
Like this:
this._adapter = new PagerAdapter(getChildFragmentManager());

Android swipe view with view pager

Based on android Creating Swipe Views with Tabs
http://developer.android.com/training/implementing-navigation/lateral.html
How can I Take listview with custom adapters and use in this example? I mean instead showing simple textview , display as.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginRight="6dip"
android:contentDescription="TODO"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/firstLine"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/icon"
android:ellipsize="marquee"
android:singleLine="true"
android:text="Description"
android:textSize="12sp" />
<TextView
android:id="#+id/secondLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/secondLine"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toRightOf="#id/icon"
android:gravity="center_vertical"
android:text="Example application"
android:textSize="16sp" />
</RelativeLayout>
Result should be as Play store application.
Thanks.
You can try to check my other posts:
Android List view layout Similar to Google play
Unable to use AndroidDrawer (sidebar like facebook)
Maybe this is what you are looking for:
How to use swipe gesture in a view pager's page with android?
Try these links..maybe this is what you are looking for.
Here's an Update
1) Make an Adapter to handle your fragments:
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
2) Add fragments: I am just adding the code for one fragment. You can follow that.
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.somefragment, container, false);//You will have your custom layout and add more items.
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
TextView tv = (TextView)getActivity().findViewById(R.id.textview1);
//You can add different items in here according to your needs.
//You will have your own code to do stuff. Like to use a listview or a gridview etc. You will make a separate adapter in a separate class and use that adapter in this onActivityCreated() method.
}
}
3) Modify the MainActivity:
public class AllActivities extends FragmentActivity implements ActionBar.TabListener {
public ViewPager viewPager;
private MyAdapter mAdapter;
private ActionBar actionBar;
private String [] tabs = {"FirstFragment","SecondFragment","ThirdFragment"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing all stuff
viewPager = (ViewPager)findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new MyAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//Add the tabs here
for(String tab_name:tabs){
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
#Override
public void onPageSelected(int position){
//on Page change, that particular page should be selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0,float arg1,int arg2){
}
#Override
public void onPageScrollStateChanged(int position){
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
}
After you have implemented this example, you don't have to worry about this MainActivity. All you have to add more fragments is that add fragments to your adapter and build pages according to that. Also, add private String [] tabs = {"FirstFragment","SecondFragment","ThirdFragment","You other fragments when you will define"};
To make google play like navigation drawer, you can refer to my first two links and make then work as you like.
Hope this one helps for what you were looking for.

Replace fragment in viewpager is not working

In my project i am using actionbar with swipeable threefragments(tabs with viewpager), i am trying to replace one of the fragment with fourth fragment, but iam not able to get it..
**Below is my code**
public class GetRideFragment extends Fragment implements ICustomDateTimeListener, SelectedLocationListener{
public GetRideFragment() {
}
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_getride, container, false);
return rootView;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fromac.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
/* Intent newintent = new Intent(getActivity(), AutoSearchActivity.class);
startActivity(newintent);
getActivity().overridePendingTransition( R.anim.slide_in_up, R.anim.slide_out_up );*/
PlaceSearchFragment fh = new PlaceSearchFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragcontainer, fh);
ft.addToBackStack("fh");
ft.commit();
}
});
Below is my layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragcontainer">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/fragcontainer"
>
<TextView
android:id="#+id/ridetitile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get a Ride"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:textColor="#33b5e5"
android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:background="#drawable/gray_btn_disabled_normal" >
...............
...........
My adpater
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new GetRideFragment();
case 1:
// Games fragment activity
return new PostRideFragment();
case 2:
// Movies fragment activity
return new SearchRidesFragment();
}
return null;
}
#Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
nNot sure where i am going wrong.Any help is appreciated.
I had the same problem. I found the solution after a lot of searches. I would see 2 problems in your code: (sorry for my bad english)
1) to change an item inside the adapter (connected to your viewpager) for a given position, you have to change the items returned by the method public Fragment getItem(int index) and call the method notifyDataSetChanged() to notify to the adapter that the content is changed.
2) the implementation of the FragmentStatePagerAdapter contains a cache based on the position and it doesn't change even if you call the notifyDataSetChanged() and you return the PagerAdapter.POSITION_NONE (there is an issue reported here: https://code.google.com/p/android/issues/detail?id=37990)
what I would suggest you is:
use a FragmentPagerAdapter, implement properly the methods getItem(int index) (with the correct item at the given position), getItemPosition(Object object), and getItemId(int position)
if you want to use a FragmentStatePagerAdapter, consider the implementation suggested in the issue I liked above (NewFragmentStatePagerAdapter).
I hope it helps!

Source Not Found when using ListFragment & ViewPager

I've been trying to create a simple Horizontal scrolling option.
I have 2 ListFragments, which I would like to scroll between.
I'm getting a "Source Not Found" error when returning the View from onCreateView function.
This is my MainActivity Class:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
final ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction fragmentTransaction) {
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
Fragment a;
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new FragmentA();
default:
return new FragmentB();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return "Section " + (position + 1);
}
}
}
This is one of my ListFragment class (the second is the same but different name & layout file):
public class FragmentA extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
}
updateStationView is a function that populates the List. removing it did not help, so I figured it's harmless.
The error is thrown right after the:
return rootView;
which returns to the onCreate functions of MainActivity.
When I'm changing the ListFragment to be a simple Fragment it works. I think I'm lacking some knowledge to figure this one out. I really want to use ListFragment...
Can someone please try an help ?
Many thanks for your efforts.
Adding the XML files:
activity_main.xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
favorites_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
I im quite sure the issue is that your custom layout for the ListFragment does not contain a ListView. These lines of code are causing the error because you need to have a ListView inside your "favourites_layout" .xml file.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.favorites_layout, container, false);
updateStationsView(0);
return rootView;
}
ListFragment has a default layout that consists of a single list view.
However, if you desire, you can customize the fragment layout by
returning your own view hierarchy from onCreateView(LayoutInflater,
ViewGroup, Bundle). To do this, your view hierarchy must contain a
ListView object with the id "#android:id/list" (or list if it's in
code)
So your layout could for example look like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
See here for more:
http://developer.android.com/reference/android/app/ListFragment.html

ViewPager with FragmentPagerAdapter does not show content

I'm trying to use the Fragment, ViewPager & co. from the Android support library v4. Fragments seem to scroll when I listen to page change events from the pager but the content is not visible. What I basically have is:
A FragmentActivity:
public class MyActivity extends FragmentActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentPagerAdapter fpa = new MyPagerAdapter(this, createFragments());
ViewPager vp = (ViewPager) findViewById(R.id.pager);
vp.setAdapter(fpa);
}
private List<Fragment> createFragments() {
List<Fragment> list = new ArrayList<Fragment>();
list.add(Fragment.instantiate(this, First.class.getName()));
list.add(Fragment.instantiate(this, Second.class.getName()));
list.add(Fragment.instantiate(this, Third.class.getName()));
return list;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
}
A FragmentPagerAdapter:
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPagerAdapter(FragmentActivity activity, List<Fragment> fragments) {
super(activity.getSupportFragmentManager());
this.fragments = fragments;
}
#Override
public Fragment getItem(int i) {
return fragments.get(i);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public boolean isViewFromObject(View view, Object o) {
return view.equals(o);
}
}
And three Fragments that look like this:
public class First extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.first, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
And they have layout like these:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:text="First Fragment"
android:id="#+id/firstText"/>
</LinearLayout>
I originally forgot to add the main layout, here it comes:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="fill_parent"/>
</LinearLayout>
I would appreciate if someone can tell me what I am doing wrong.
This is because you have overridden isViewFromObject in MyPagerAdapter.
FragmentPagerAdapter handles isViewFromObject, so you shouldnt override it.
As with me, I reckon most visitors to this post started with a basic PagerAdapter, then realised they needed to page fragments and changed their base class without realising the consequences. Unfortunate, but I couldn't criticise the Android team for this.
Ya correct as Ian Newson told, just remove isViewFromObject overrided method from your code
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}

Categories

Resources