android actionbar tab viewpage AsyncTask first tab is empty when started - android

it is a few days I try to solve this problem whitout success. Please help me.
I use the tabs navigation with viewpager.There are four fragments. I use async task for download the data I need to put in the view. when the app is started, the first fragments is ampty. But when i swipe to the second or the third, they have data. if i swipe from the second to the first, it has data too. so i guess i may be something wrong with notifyDataSetChanged, but i tried and it doesnt work.
MainActivity.java
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);
actionBar.setDisplayShowTitleEnabled(false);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
//private ArrayList hasLoadedPages = new ArrayList<Integer>();
#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));
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
//case 0:
// return new LaunchpadSectionFragment();
default:
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
}
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
String str="";
if (position==0){
str = "one";
}else if(position==1){
str = "two";
}else if(position==2){
str = "three";
}else if(position==3){
str = "four";
}
return str;
}
#Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
}
public static class DummySectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Bundle args = getArguments();
mCid = args.getInt(ARG_SECTION_NUMBER);
mNewsData = new ArrayList<HashMap<String,Object>>();
mNewsList = (ListView)getView().findViewById(android.R.id.list);
mNewsListAdapter = new SimpleAdapter(this.getActivity(), mNewsData, R.layout.newslist_item,
new String[]{"newslist_item_title","newslist_item_digest","newslist_item_source","newslist_item_ptime"},
new int[]{R.id.newslist_item_title,R.id.newslist_item_digest,R.id.newslist_item_source,R.id.newslist_item_ptime});
View loadMoreLayout = this.getLayoutInflater(savedInstanceState).inflate(R.layout.loadmore, null);
mNewsList.setAdapter(mNewsListAdapter);
mNewsList.addFooterView(loadMoreLayout);
mNewsList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Intent intent = new Intent(getActivity(), NewsDetailsActivity.class);
startActivity(intent);
intent.putExtra("newsDate", mNewsData);
intent.putExtra("position", position);
startActivity(intent);
}
});
mLoadMoreBtn = (Button)getView().findViewById(R.id.loadmore_btn);
mLoadMoreBtn.setOnClickListener(loadMoreListener);
loadNewsAsyncTask = new LoadNewsAsyncTask();
loadNewsAsyncTask.execute(mCid,0,true);
}
}
private static class LoadNewsAsyncTask extends AsyncTask<Object, Integer, Integer>
{
#Override
protected void onPreExecute()
{
mLoadMoreBtn.setText(R.string.loadmore_txt);
}
#Override
protected Integer doInBackground(Object... params)
{
return getSpeCateNews((Integer)params[0],mNewsData,(Integer)params[1],(Boolean)params[2]);
}
#Override
protected void onPostExecute(Integer result)
{
switch (result)
{
case NONEWS:
mLoadMoreBtn.setText(R.string.no_news);
break;
case NOMORENEWS:
mLoadMoreBtn.setText(R.string.no_more_news);
break;
case LOADERROR:
mLoadMoreBtn.setText(R.string.load_news_failure);
break;
}
mNewsListAdapter.notifyDataSetChanged();
mLoadMoreBtn.setText(R.string.loadmore_btn);
}
}

You are using FragmentPagerAdapter please change it to FragmentStatePagerAdapter and run again
Difference between FragmentPagerAdapter and FragmentStatePagerAdapter
About FragmentPagerAdapter Google's guide says:
This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.
And about FragmentStatePagerAdapter:
This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.

Related

how to display toast messages for each tab in swipe tab in android?

when i run this code,the toast in two different fragments are displayed on one tab. when i swipe to next tab nothing is displayed.
this is is my main tab activity:
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Offers", "Distance", "Happy Hours","Shop List" };
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
this is adapter class :
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
Bundle bundle = new Bundle();
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
Fragment of = new OfferFragment();
bundle.putString("OfferFragment", "OfferFragment");
of.setArguments(bundle);
return of;
case 1:
Fragment df = new DistanceFragment();
bundle.putString("DistanceFragment", "DistanceFragment");
df.setArguments(bundle);
return df;
case 2:
Fragment hf = new HappyHoursFragment();
bundle.putString("HappyHoursFragment", "HappyHoursFragment");
hf.setArguments(bundle);
return hf;
case 3:
Fragment sf = new ShoplistFragment();
bundle.putString("ShoplistFragment", "ShoplistFragment");
sf.setArguments(bundle);
return sf;
}
return null;
}
#Override
public int getCount() {
return 4;
}
}
this is my first fragment :
public class OfferFragment extends Fragment {
private String name;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// public static final String ARG_OBJECT = "object";
View rootView = inflater.inflate(R.layout.offerfragment, container,
false);
Bundle args = getArguments();
TextView txtview = (TextView) rootView.findViewById(R.id.offer);
name = args.getString("OfferFragment");
txtview.setText(args.getString("OfferFragment"));
display();
return rootView;
}
private void display() {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), name, Toast.LENGTH_SHORT).show();
}
}
this is my second fragment :
public class DistanceFragment extends Fragment {
private String name;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.distancefragment, container, false);
Bundle args = getArguments();
TextView txtview = (TextView) rootView.findViewById(R.id.distance);
name = args.getString("DistanceFragment");
txtview.setText(args.getString("DistanceFragment"));
display();
return rootView;
}
private void display() {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), name, Toast.LENGTH_SHORT).show();
}
}
any suggestions are appreciated. am stuck with this.
This is because next fragment is created by pager
before showing toast check if that fragment is visible or not
if(fragmentName.this.isVisible())
{
// do your stuff here
}
Write onResume() in every fragment class.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Display Toast message here
}
}

Get fragment activity outside of Fragment.OnCreateView()

I have a Fragment with a TableLayout. The data in the table is from a SQLite db. The SQLite db is populated from a RESTful webservice in an AsyncTask in the MainActivity. The Fragment must wait for the task to complete before populating the table. The Fragment listens for the task onPostExecute() method to be called. When it is, the method onLoadAndStoreComplete in the Fragment is called. This all works.
What doesn't work is that I need the fragment activity in order to create new TableRows and TextViews in onLoadAndStoreComplete and I can't get it.
I've tried:
- making a class member fragmentActivity and assigning in onCreateView(), but by the time it gets to onLoadAndStoreComplete(), it is null.
- calling this.getActivity() again in onLoadAndStoreComplete(), but it returns null.
How do I get the fragment activity?
MyFragment.java:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentActivity = this.getActivity(); // return value is valid
...
}
#Override
public void onLoadAndStoreComplete() {
fragmentActivity = this.getActivity(); // returns null
...
}
from MainActivity.java (extends ActionBarActivity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = this;
setContentView(R.layout.activity_main);
Resources resources = getResources();
String[] tabTitleArray = { resources.getString(R.string.first_fragment),
resources.getString(R.string.second_fragment),
resources.getString(R.string.help_fragment) };
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab_name : tabTitleArray) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
// On swiping the ViewPager, select the respective tab
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position) ;// on changing the page, make respected tab selected
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
String url = "http://myrestfulwebservice";
Fragment secondFragment = mAdapter.getItem(SECOND_TAB);
new LoadAndStoreDataTask((OnLoadAndStoreCompleteListener)secondFragment).execute(url);
}
} // end OnCreate
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new HelpFragment();
}
return null;
}
#Override
public int getCount() {
return 3; // get item count - equal to number of tabs
}
public static void setTabColor(TabHost tabhost) {
for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
}
tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
}
}
I haven't tested this, but it seems to me that it would work.
Add a Context parameter to the constructor for both TabsPagerAdapter and MyFragment.
Something like this:
TabsPagerAdapter.java:
public class TabsPagerAdapter extends FragmentPagerAdapter {
private Context mCtx;
public TabsPagerAdapter(FragmentManager fragmentManager, Context context) {
super(fragmentManager);
mCtx = context;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment(mCtx);
case 1:
return new SecondFragment(mCtx);
case 2:
return new HelpFragment(mCtx);
}
return null;
}
#Override
public int getCount() {
return 3; // get item count - equal to number of tabs
}
public static void setTabColor(TabHost tabhost) {
for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
}
tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
}
}
MainActivity.java:
mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager(), this);
MyFragment.java (do this in FirstFragment, SecondFragment, and HelpFragment):
public static class MyFragment extends Fragment {
private Context fragmentActivity ;
public MyFragment(Context context){
fragmentActivity = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//.........
return rootView;
}
#Override
public void onLoadAndStoreComplete() {
//do something with fragmentActivity
}
}
It seems the AsyncTask starts too early. suggest loading the db in onActivityCreated(), it's be called after onCreateView
#Override
public void onActivityCreated (Bundle savedInstanceState) {
//load your db here
}

Show a detail fragment when clicking an item in a ListFragment in Android Studio

My app has a tab bar that should be visible at all times. The first tab contains a ListFragment. When I click on an item within, it loads a new activity that creates a detail fragment displaying the contents of the object in the list. I would like to display this content without having to start a new activity because it also destroys the tab bar!
Any help would be greatly appreciated!
To illustrate, here are some screenshots and code:
This is the code for the FragmentActivity that creates the tabs:
public class MainFragmentActivity extends FragmentActivity
implements ActionBar.TabListener {
SectionsPagerAdapter sectionsPagerAdapter = null;
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
sectionsPagerAdapter =
new SectionsPagerAdapter
(
getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
}); // End of sectionPageAdapter.
Tab browseTab = actionBar.newTab();
browseTab.setIcon(R.drawable.search);
browseTab.setTabListener(this);
actionBar.addTab(browseTab);
Tab myStuffTab = actionBar.newTab();
myStuffTab.setIcon(R.drawable.my_stuff);
myStuffTab.setTabListener(this);
actionBar.addTab(myStuffTab);
Tab profileTab = actionBar.newTab();
profileTab.setIcon(R.drawable.profile);
profileTab.setTabListener(this);
actionBar.addTab(profileTab);
Tab settingsTab = actionBar.newTab();
settingsTab.setIcon(R.drawable.settings);
settingsTab.setTabListener(this);
actionBar.addTab(settingsTab);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment browseFragment = new BrowseFragment();
Bundle browseArgs = new Bundle();
browseArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
browseFragment.setArguments(browseArgs);
return browseFragment;
case 1:
Fragment myStuffFragment = new MyStuffFragment();
Bundle myStuffArgs = new Bundle();
myStuffArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
myStuffFragment.setArguments(myStuffArgs);
return myStuffFragment;
case 2:
Fragment profileFragment = new ProfileFragment();
Bundle profileArgs = new Bundle();
profileArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
profileFragment.setArguments(profileArgs);
return profileFragment;
case 3:
Fragment settingsFragment = new SettingsFragment();
Bundle settingsArgs = new Bundle();
settingsArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
settingsFragment.setArguments(settingsArgs);
return settingsFragment;
}
return null;
}
// There are always 4 tabs
#Override
public int getCount() {
return 4;
}
// Return a CharSequence for the selected tab
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase();
case 1:
return getString(R.string.title_section2).toUpperCase();
case 2:
return getString(R.string.title_section3).toUpperCase();
case 3:
return getString(R.string.title_section4).toUpperCase();
}
return null;
}
}
} // End of class.
This is the code for the first tab:
public class BrowseFragment extends ListFragment {
public static String sectionNumberKey = "sec_num";
private String activityName = "Browse";
int currentPosition = 0;
List<Listing> listings = new ListingData().getListings();
public BrowseFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BrowseArrayAdapter adapter = new BrowseArrayAdapter(getActivity(),
R.layout.browselist_item,
listings);
setListAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_browse,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.section_label);
int intSectionNumber = getArguments().getInt(sectionNumberKey);
String numAsString = Integer.toString(intSectionNumber);
tv.setText(numAsString);
activityName += " " + numAsString;
return rootView;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
showDetails(position);
}
void showDetails(int index) {
currentPosition = index;
Intent intent = new Intent();
intent.setClass(getActivity(), BrowseDetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
And here is the code for the Detail Activity:
public class BrowseDetailsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
BrowseDetailFragment details = new BrowseDetailFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}
}
Basicly you just have to use the content of the onCreate method from your BrowseDetailActivity in the showDetails method of your BrowseFragment. In this way, you can drop your BrowseDetailsActivity.
BrowseFragment.java
void showDetails(int index) {
BrowseDetailFragment details = BrowseDetailFragment.newInstance(index);
getChildFragmentManager().beginTransaction().add(details).commit();
}
And use the static newInstance method inside your BrowseDetailFragment like so:
BrowseDetailFragment.java
public class BrowseDetailFragment extends Fragment {
private int position;
public static BrowseDetailFragment newInstance(int position) {
BrowseDetailFragment fragment = new BrowseDetailFragment();
fragment.position = position;
return fragment;
}
public BrowseDetailFragment() {
//Required empty constructor
}
//Lifecycle methods and logics
}
Make sure to provide some navigation option so users can return to your list.

retain state of viewpager fragments android

I have a viewpager in a fragment in which i am showing 3 fragments but when I open the fragment first time it opens fine and when I move to another fragment and came back to the viewpager fragment it doesn't show the fragments in view pager then I have to either change the orientation of the phone or keep swiping the viewpager for the hidden fragments to show.
I have googled it and now I know I have to set the tag to each fragment and retrieve fragment with findfragmentbytag method but problem is when I try to set the tag to fragment
getSupportFragmentManager().beginTransaction().add(myFragment, "Some Tag").commit();
above line crashes my app and logcat shows "cant set tag to fragment", I know I'm doing some stupid mistake
this is the complete code of my fragment. I would really appreciate if one could guide me where to write the code for setting the tag of fragments. thanks in advance.
public class MatchesListingFragment extends Fragment implements ActionBar.TabListener {
Context context;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
ActionBar actionBar;
Matchlistings db;
Bundle savedInstanceState;
Fragment livescore,fixture,results;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.savedInstanceState = savedInstanceState;
db = new Matchlistings(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_matches, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
context = getActivity().getApplicationContext();
if(savedInstanceState == null){
livescore = new LiveScoreListingFragment();
fixture = new FixturesListingFragment();
results = new ResultsListingFragment();
}
if(!Constants.is_listing_refreshed){
Log.i(MainActivity.TAG,"refreshing list");
db.loadListingsFromServer().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
actionBar = getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
if(mSectionsPagerAdapter == null)
mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
mViewPager = (ViewPager) getView().findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
Tab tb = actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this);
actionBar.addTab(tb);
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Fragment fragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
fragment = livescore;
return fragment;
case 1:
fragment = fixture;
return fragment;
case 2:
fragment = results;
return fragment;
case 3:
fragment = new LiveScoreListingFragment();
return fragment;
}
return null;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "LIVE";
case 1:
return "FIXTURES";
case 2:
return "RESULTS";
case 3:
return "HOT";
}
return null;
}
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
actionBar.removeAllTabs();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
#Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
#Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
}
EDIT:
i have now tried to get the fragment from viewpager by tag instead of creating new fragment everytime. but problem is still same.
FixturesListingFragment fixture = (FixturesListingFragment) getActivity().getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.pager+":1");
if(fixture == null)
fixture = new FixturesListingFragment();
Have you tried to use setOffscreenPageLimit? if you have 3 pages then set it to 2. This way pages won't be recreated even if the app is on iddle state. Here is the link
I Have solved thiw problem by just using setOffScreenpageLimit(int) to the number of additional tabs that I have.
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentHome(), "Home");
adapter.addFragment(new FragmentEProfile(), "e-Profile");
adapter.addFragment(new FragmentResults(), "Results");
adapter.addFragment(new FragmentOutpass(), "Outpass");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
}
i have fixed the issue by changing FragmentPagerAdapter to FragmentStatePagerAdapter...
this is what i read in the sample app downloaded from this link
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
* three primary sections of the app. We use a {#link android.support.v4.app.FragmentPagerAdapter}
* derivative, which will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
and changed it.. but still wondering there should be a way to do it with FragmentPagerAdapter
Try to retain the instance as mentioned below:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//add this line
setRetainInstance(true);
context = getActivity().getApplicationContext();

FragmentPagerAdapter getItem error with ListFragment

I've looked at quite a lot of code and can't figure this out. http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
It has to be something simple.
I'm showing most of the code. The error is in the next section.
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
public static final int TAB_COUNT = 3;
public static InputMethodManager inputManager;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
// To control keyboard pop-up
inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab,
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,
FragmentTransaction fragmentTransaction) {
}
This is where my error is.
case 1 of getItem, Type mismatch: Cannot convert from MainActivity.HistoryFragment to Fragment. it is telling me to either change method return type to HistoryFragment or change return type of newInstance() to Fragment. Where I can't do either. Other examples I've seen look almost identical to my code. I have tried with and without passing an argument.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
Fragment tipCalc = new TipCalcFragment();
return tipCalc;
case 1:
// Fragment history = new HistoryFragment();
return HistoryFragment.newInstance(i); //ERROR HERE
case 2:
Fragment stats = new StatsFragment();
return stats;
}
return null;
}
And my HistoryFragment that extends ListFragment. In the end it won't be pulling from the String[] values but from database resources. I just wanted to setup a structure first and see it/play with the layout.
public static class HistoryFragment extends ListFragment {
// public HistoryFragment() {
// }
String[] values = new String[] { ... };
static HistoryFragment newInstance(int num) {
HistoryFragment history = new HistoryFragment();
Bundle args = new Bundle();
args.putInt("num", num);
history.setArguments(args);
return history;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.history, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1,
values));
}
}
I figured it out after getting some sleep. I was importing android.app.ListFragment instead of android.support.v4.app.ListFragment
I think you will have to typecast to fragment before returning. So try this
Fragment history = HistoryFragment.newInstance(i);
return history;

Categories

Resources