I created a swipe tab view inside a fragment. I tested this in a FragmentActivity with no issues. I tested with pages that consisted of different fragment classes and fragments all from the same class... again no issues.
Then, I changed the FragmentActivity to a Fragment. I tested again with different Fragment classes representing each page and had no problem. Finally, i repeated the test with fragments of the same class and ran into issues.
There are 3 pages right now representing three weeks. At first week 1 shows up. I swipe to week 2 and there is nothing. I swipe to week 3 and nothing again. When I swipe back to week 1, the only viewable page ends up being the middle page. Is this an issue with fragment life cycles? I'm not sure how to debug this special circumstance. I'm looking for possible causes so I can start solving this issue.
public class WeeklyScrollTab extends Fragment {
private ViewPager my_view_pager;
private View my_layout;
private int my_current_page;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
my_layout = inflater.inflate(R.layout.weekly_scroll_tabs, container, false);
return my_layout;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Getting the arguments to the Bundle object */
//Bundle data = getArguments();
/** Getting integer data of the key current_page from the bundle */
//my_current_page = data.getInt("week_val", 0);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
my_view_pager = (ViewPager)my_layout.findViewById(R.id.week_list_pager);
FragmentManager manager = getActivity().getSupportFragmentManager();
//FragmentManager manager = getChildFragmentManager();
my_view_pager.setAdapter(new WeeklyScrollAdapter(manager));
super.onActivityCreated(savedInstanceState);
}
public int getCurrentPage(){
return my_current_page;
}
public class WeeklyScrollAdapter extends FragmentStatePagerAdapter {
public WeeklyScrollAdapter(FragmentManager the_manager){
super(the_manager);
}
#Override
public Fragment getItem(int the_position) {
Fragment fragment1 = null;
if(the_position == 0){
fragment1 = new MyNflPlayerList();
Bundle args1 = new Bundle();
args1.putInt("week_val"+the_position, the_position);
fragment1.setArguments(args1);
}
if(the_position == 1){
fragment1 = new MyNflPlayerList();
Bundle args2 = new Bundle();
args2.putInt("week_val"+the_position, the_position);
fragment1.setArguments(args2);
}
if(the_position == 2){
fragment1 = new MyNflPlayerList();
Bundle args3 = new Bundle();
args3.putInt("week_val"+the_position, the_position);
fragment1.setArguments(args3);
}
return fragment1;
}
/**
*
* #return number of total pages
*/
#Override
public int getCount() {
return 3;
}
/**
* gets title for tab
*/
#Override
public CharSequence getPageTitle(int position) {
if(position ==0){
return "Week 1";
}
if(position == 1){
return "Week 2";
}
if(position == 2){
return "Week 3";
}
return super.getPageTitle(position);
}
public class NflPlayerAdapter extends BaseAdapter {
private ArrayList<NflPlayerModel> my_list;
private Context my_context;
public NflPlayerAdapter(Context c){
my_context = c;
my_list = new ArrayList<NflPlayerModel>();
my_list.add(new NflPlayerModel("T.","Brady","NE","QB",56));
my_list.add(new NflPlayerModel("A.","Peterson","MN","RB",24));
my_list.add(new NflPlayerModel("D.","Bryant","DAL","WR",18));
my_list.add(new NflPlayerModel("M.","Gattica","TB","K",9));
}
#Override
public int getCount() {
return my_list.size();
}
#Override
public NflPlayerModel getItem(int i) {
return my_list.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//getting the data and injecting it into the each row view
View row = convertView;
NflPlayerHolder holder = null;
if(row == null){
LayoutInflater inflater = (LayoutInflater)my_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.my_nfl_player_row,parent, false);
holder = new NflPlayerHolder(row);
row.setTag(holder);
}
else{
holder = (NflPlayerHolder) row.getTag();
}
NflPlayerModel temp = my_list.get(position);
holder.getFname().setText(temp.getFname());
holder.getLname().setText(temp.getLname());
holder.getTeam().setText(temp.getTeam());
holder.getPosition().setText(temp.getPosition());
holder.getPoints().setText(Integer.toString(temp.getPoints()));
return row;
}
class NflPlayerHolder {
/**
* TextView object in my_league_row xml.
*/
private TextView my_fname;
private TextView my_lname;
private TextView my_team;
private TextView my_position;
private TextView my_points;
/**
* Constructor. Converts the xml txt_league_name to Java object.
* #param v
*/
public NflPlayerHolder(View v){
my_fname = (TextView)v.findViewById(R.id.player_fname);
my_lname = (TextView)v.findViewById(R.id.player_lname);
my_team = (TextView)v.findViewById(R.id.player_team);
my_position = (TextView)v.findViewById(R.id.player_position);
my_points = (TextView)v.findViewById(R.id.player_points);
}
public TextView getFname(){
return my_fname;
}
public TextView getLname(){
return my_lname;
}
public TextView getTeam(){
return my_team;
}
public TextView getPosition(){
return my_position;
}
public TextView getPoints(){
return my_points;
}
public class MyNflPlayerList extends Fragment implements AdapterView.OnItemClickListener{
private View my_layout;
private ListView my_list_view;
private static HomeActivityCommunicator my_communicator;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
my_layout = inflater.inflate(R.layout.my_nfl_player_list, container, false);
return my_layout;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
my_list_view = (ListView)getActivity().findViewById(R.id.nfl_player_list_view);
NflPlayerAdapter adapter = new NflPlayerAdapter(getActivity());
my_list_view.setAdapter(adapter);
my_list_view.setOnItemClickListener(this);
super.onActivityCreated(savedInstanceState);
}
public void setHomeActivityCommunicator(HomeActivityCommunicator the_communicator){
my_communicator = the_communicator;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.e("mike", "the player index is " + i);
my_communicator.onMyNflPlayerListSelection(i);
}
Related
I am developing an application for on-line shopping. Due to the big number of products that I have to display I have used a lot of categorization. One of the main feature that I am using is ViewPager with PageAdapter. In every fragment it's supposed to be different layouts. In one of the fragments I have used a GridView. The problem is that when I switch between pages, and I return to the first page the size of the GridView , the number of elements inside keeps growing repeating themselves. For example if I have 12 elements at the beginning, after I switch pages and then get back again it becomes 24, 36 etc.
Below is the code I used for this:
EbuyHomeScreen.class
public class EbuyHomeScreen extends FragmentActivity {
#SuppressLint("InlinedApi") protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ebuy_home_screen);
/** Getting a reference to the ViewPager defined the layout file */
ViewPager pager = (ViewPager) findViewById(R.id.pager);
/** Getting fragment manager */
FragmentManager fm = getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
EbuyFragmentPagerAdapter pagerAdapter = new EbuyFragmentPagerAdapter(fm);
/** Setting the pagerAdapter to the pager object */
pager.setAdapter(pagerAdapter);
}
EbuyFragmentPagerAdapter.class
public class EbuyFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
/** Constructor of the class */
public EbuyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
/** This method will be invoked when a page is requested to create */
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
EbuyFragmentLatest myFragmentLatest = new EbuyFragmentLatest();
return myFragmentLatest;
case 1:
EbuyFragmentSold myFragmentSold = new EbuyFragmentSold();
return myFragmentSold;
case 2:
EbuyFragmentSponsored myFragmentSponsored = new EbuyFragmentSponsored();
return myFragmentSponsored;
default:
EbuyFragmentLatest myFragmentLatestDefault = new EbuyFragmentLatest();
return myFragmentLatestDefault;
}
}
/** Returns the number of pages */
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
/** code for returning the title*/ }
}
}
EbuyFragmentLatest.class
public class EbuyFragmentLatest extends Fragment {
final ArrayList<EbuyItem> ebuy_data = new ArrayList<EbuyItem>();
private EbuyItemAdapter customAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.ebuy_home_fragment_latest,
container, false);
JazzyGridView mGrid = (JazzyGridView)v.findViewById(R.id.ebuy_list);
mGrid.setTransitionEffect(JazzyHelper.TILT);
ebuy_data.add(new EbuyItem("http://www.ebuy.al/Images/dsc/8884_400_300.jpg","Fustan Glamour","2,500L [17.9 €]"));
/*
** filing with data continues */
customAdapter = new EbuyItemAdapter(
container.getContext(), ebuy_data);
mGrid.setAdapter(customAdapter);
return v;
}
}
And this is the last class EbuyItemAdapter.class
public class EbuyItemAdapter extends BaseAdapter {
private ArrayList<EbuyItem> ebuy_data;
private LayoutInflater layoutInflater;
public EbuyItemAdapter(Context context, ArrayList<EbuyItem> ebuy_data) {
this.ebuy_data = ebuy_data;
layoutInflater = LayoutInflater.from(context);
}
public int getCount() {
return ebuy_data.size();
}
public Object getItem(int position) {
return ebuy_data.get(position);
}
public long getItemId(int position) {
return position;
}
#SuppressLint({ "DefaultLocale", "InflateParams" })
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.ebuy_item, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.price = (TextView) convertView.findViewById(R.id.price);
holder.image = (ImageView) convertView
.findViewById(R.id.ebuy_image);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(((EbuyItem) ebuy_data.get(position)).getName());
holder.price.setText(((EbuyItem) ebuy_data.get(position)).getPrice());
UrlImageViewHelper.setUrlDrawable(holder.image,
((EbuyItem) ebuy_data.get(position)).getImageUrl(),
R.drawable.loading);
return convertView;
}
static class ViewHolder {
TextView name;
TextView price;
ImageView image;
}
}
i have a fragment which uses AsyncTask to download the JSON and display several NEWS segments. Here i can slide up and down and view all the News segments. But i want to slide this horizontally and view the news segments one by one by sliding. As far as i know (i'm a beginner) i have to use a ViewPager adapter to achive this.But i don't know how.Please someone help me.
My fragment class
public class NewsDetailFragment extends Fragment {
private View view1;
private ArrayList<BaseElement> newsdetail;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
private ProgressDialog dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsdetail_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
view1 = (View) view.findViewById(R.id.list);
dialog = new ProgressDialog(NewsDetailFragment.this.getActivity());
dialog.setMessage("Loading News");
dialog.setCancelable(true);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
newsdetail = JSONServices.getNewsDescription();
return null;
}
#SuppressWarnings("unchecked")
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setTheater(newsdetail);
adapter = new LazyAdapter(newsdetail, activity,Element.NEWS_DETAIL.getType());
((AdapterView<ListAdapter>) view1).setAdapter(adapter);
dialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog.show();
super.onPreExecute();
}
}
}
My ViewPager adapter
public class ViewPageAdapter extends PagerAdapter {
private LinkedHashMap<String, BaseElement> item;
private int page;
private Activity activity;
private LayoutInflater inflater;
private ViewPageAdapter(LinkedHashMap<String, BaseElement> item, int page,
Activity activity) {
super();
this.item = item;
this.page = page;
this.activity = activity;
}
#Override
public int getCount() {
return item.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
// TODO Auto-generated method stub
return view == (LinearLayout) object;
}
#Override
public Object instantiateItem(View container, int position) {
View view = null;
return view;
}
}
PageAdapter
public class PageAdapter extends FragmentStatePagerAdapter {
public static final String ARG_SECTION_NUMBER = "section_number";
private ArrayList<BaseElement> item;
private Activity activity;
public PageAdapter(FragmentManager fragmentManager,
ArrayList<BaseElement> item, Activity activity) {
super(fragmentManager);
this.activity = activity;
this.item = item;
}
#Override
public Fragment getItem(int position) {
// ------set fragment class for viewPager----------//
Fragment fragment = new PageSectionFragment();
Bundle bundle = new Bundle();
// ---- setPage position as agument for PageSectionFragment
// class---//
bundle.putInt(ARG_SECTION_NUMBER, position);
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
return item.size();
}
#Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
#Override
public CharSequence getPageTitle(int position) {
FilmCategory film = (FilmCategory) item.get(position);
Sihala sinhla = new Sihala(activity);
return sinhla.getSinhalaString(film.getCategory());
}
}
Add this into your layout..
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never" />
Then Add this class into your Fragment class.
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
/*#Override
public android.support.v4.app.Fragment getItem(int position) {
return AlertSlideFragment.create(position);
}*/
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
tabFragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
tabFragment.setArguments(args);
/*fragment = getRegisteredFragment(0);*/
return tabFragment;
}
#Override
public int getCount() {
return NUM_PAGES;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container,
position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
Finally here is the DummySectionFragment
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// View rootView = null;
/*View rootView = inflater.inflate(R.layout.fragment_tabbed_dummy,
container, false);
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));*/
int screenNum = getArguments().getInt(ARG_SECTION_NUMBER);
//listAdapterAlert= new ListAdapterAlert(getActivity(), R.layout.alert_list);
if(screenNum == 0) // 0 for recent
{
rootView = inflater.inflate(R.layout.alert_list,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.tv);
}
else if(screenNum == 1) // 1 for by due date
{
rootView = inflater.inflate(R.layout.alert_list,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.tv);
}
else if(screenNum == 2) // 2 for by campaign
{
rootView = inflater.inflate(R.layout.campaign_alert,
container, false);
}
return rootView;
}
}
Hope it will help you.
I created a ViewPager that uses individual Fragments. There are 3, here is an example of one of them:
public class PainFragment extends Fragment {
private TextView mTxtScale;
private Button mBtnMinus;
private Button mBtnPlus;
private int mScale;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pain, container, false);
mTxtScale = (TextView)v.findViewById(R.id.scale);
mBtnMinus = (Button)v.findViewById(R.id.minus);
mBtnPlus = (Button)v.findViewById(R.id.plus);
mScale = Integer.valueOf(mTxtScale.getText().toString());
mBtnMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mScale--;
if(mScale == -1) {
mScale = 9;
}
mTxtScale.setText(String.valueOf(mScale));
}
});
mBtnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mScale++;
if(mScale == 10) {
mScale = 0;
}
mTxtScale.setText(String.valueOf(mScale));
}
});
return v;
}
public static PainFragment newInstance(String text) {
PainFragment f = new PainFragment();
Bundle b = new Bundle();
//b.putString("msg", text);
f.setArguments(b);
return f;
}
public int getScale() {
int scale = Integer.valueOf(mTxtScale.getText().toString());
return scale;
}
And I instantiated the ViewPager in my MainFragment:
public class MainFragment extends Fragment {
Entry mEntry = new Entry();
ViewPager mPager;
JournalPagerAdapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_screen, container, false);
mPager = (ViewPager)rootView.findViewById(R.id.pager);
mPager.setOffscreenPageLimit(2); // So all 3 pages are loaded at once.
mAdapter = new JournalPagerAdapter(getActivity().getSupportFragmentManager());
mPager.setAdapter(mAdapter);
...
I have button click listeners in the ViewPager Fragments. I would like to know the best way to set up a listener so that my main fragment can detect when a button is pressed on one of the ViewPager fragments.
/** Update - Here is my adapter class **/
public class JournalPagerAdapter extends FragmentPagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public JournalPagerAdapter(FragmentManager mgr) {
super(mgr);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return PainFragment.newInstance("PainFragment");
case 1: return StressFragment.newInstance("StressFragment");
case 2: return SleepFragment.newInstance("SleepFragment");
default: return PainFragment.newInstance("PainFragment");
}
}
#Override
public int getCount() {
return 3;
}
/* Thanks to Streets of Boston (http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager)
* for the next 3 methods, should include in all PagerAdapters. Let's you get the fragment instances by position */
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
Second answer with pseudo example of using a ClickListener instead of the Callback. This should let you keep all logic out of the Activity.
Implement OnClickListener interface in MainFragment. Add a OnClickListener to your JournalPagerAdapter constructor. Presumably the Adapter is creating the PainFragments. Add OnClickListener to PainFragment newInstance and have the Adapter provide it when it creates each PainFragment.
public class PainFragment extends Fragment {
private TextView mTxtScale;
private Button mBtnMinus;
private Button mBtnPlus;
private int mScale;
protected OnClickListener mainClickListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pain, container, false);
mTxtScale = (TextView)v.findViewById(R.id.scale);
mBtnMinus = (Button)v.findViewById(R.id.minus);
mBtnPlus = (Button)v.findViewById(R.id.plus);
mScale = Integer.valueOf(mTxtScale.getText().toString());
mBtnMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mScale--;
if(mScale == -1) {
mScale = 9;
}
mTxtScale.setText(String.valueOf(mScale));
mainClickListener.onClick(view);
}
});
mBtnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mScale++;
if(mScale == 10) {
mScale = 0;
}
mTxtScale.setText(String.valueOf(mScale));
mainClickListener.onClick(view);
}
});
return v;
}
public static PainFragment newInstance(String text, OnClickListener onClickListener) {
PainFragment f = new PainFragment();
f.mainClickListener = onClickListener;
Bundle b = new Bundle();
//b.putString("msg", text);
f.setArguments(b);
return f;
}
public int getScale() {
public class MainFragment extends Fragment implements OnClickListener {
Entry mEntry = new Entry();
ViewPager mPager;
JournalPagerAdapter mAdapter;
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_screen, container, false);
mPager = (ViewPager)rootView.findViewById(R.id.pager);
mPager.setOffscreenPageLimit(2); // So all 3 pages are loaded at once.
mAdapter = new JournalPagerAdapter(getActivity().getSupportFragmentManager(), this);
mPager.setAdapter(mAdapter);
...
public class JournalPagerAdapter extends FragmentPagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private OnClickListener mOnClickListener;
public JournalPagerAdapter(FragmentManager mgr, OnClickListener onClickListener) {
super(mgr);
mOnClickListener = onClickListener;
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return PainFragment.newInstance("PainFragment", mOnClickListener);
case 1: return StressFragment.newInstance("StressFragment", mOnClickListener);
case 2: return SleepFragment.newInstance("SleepFragment", mOnClickListener);
default: return PainFragment.newInstance("PainFragment", mOnClickListener);
}
}
...
The proper way to achieve this is probably through the use of a callback. Your fragment would utilize a normal click listener which would then use a callback to communicate back to the hosting Activity.
See the Android docs regarding communicating from a Fragment back to the Activity; then the Activity can communicate it to other Fragments.
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.
I have a FragmentActivity that uses a ViewPager to flip left and right through pages of data (two ListFragments).
public class StopsActivity extends FragmentActivity {
private ViewPager mViewPager;
private PagerTabStrip mPagerTabStrip;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stops);
mPagerTabStrip =(PagerTabStrip)findViewById(R.id.pager_header);
mViewPager = (ViewPager)findViewById(R.id.pager);
mPagerTabStrip.setDrawFullUnderline(true);
mPagerTabStrip.setTabIndicatorColorResource(R.color.pagerTabStrip);
mViewPager.setAdapter(new StopsAdapter(getSupportFragmentManager()));
mViewPager.setCurrentItem(0);
}
private class StopsAdapter extends FragmentPagerAdapter {
public StopsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return StopsFragment.newInstance(routename, Stop.FORWARD);
case 1:
return StopsFragment.newInstance(routename, Stop.BACKWARD);
}
return null;
}
#Override
public int getCount() { return 2;}
#Override
public CharSequence getPageTitle(int position) { /* implementation ... */}
}
}
Everything runs ok, but I think that the instantation of the second StopFragment invalidate the data of the first one when getItem is called.
public class StopsFragment extends ListFragment {
private StopsAdapter mStopsAdapter;
private ListView mListView;
private String routename;
private int direction;
public static StopsFragment newInstance(String routename, int direction) {
StopsFragment stopsFragment = new StopsFragment();
// Supply arguments
Bundle args = new Bundle();
args.putString("routename", routename);
args.putInt("direction", direction);
stopsFragment.setArguments(args);
return stopsFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the adapter
ArrayList<Stop> stops = ...
mStopsAdapter = new StopsAdapter(getActivity(), stops);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) {
View rootView = inflater.inflate(R.layout.fragment_stops, container, false);
// Attach the adapter
mListView = (ListView) rootView.findViewById(android.R.id.list);
mListView.setAdapter(mStopsAdapter);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
The page "IDA" corresponds to StopFragment with argument Stop.FORWARD and the page "VUELTA" corresponds the StopFragment with argument Stop.BACKWARD. As you can see in the images below, just one of them (the last one instantiate) is populated:
What I'm doing wrong?
EDIT
This is StopsAdapter
class StopsAdapter extends BaseAdapter {
private ArrayList<Stop> stops;
private LayoutInflater inflater;
public StopsAdapter(Context context, ArrayList<Stop> stops) {
this.stops = stops;
this.inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return stops.size();
}
#Override
public Object getItem(int position) {
return stops.get(position);
}
#Override
public long getItemId(int position) {
return (long)position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_stop, parent, false);
}
TextView name = (TextView)convertView.findViewById(R.id.tvStopName);
TextView description = (TextView)convertView.findViewById(R.id.tvStopDescription);
Stop stop = (Stop)getItem(position);
name.setText(stop.name);
if (stop.info != null) {
description.setText(stop.info);
}
return convertView;
}
}
Ok, my fault. The code that was giving me problems is the only that I haven't posted (ArrayList<Stop> stops = ...). The code about Fragments and ViewPager works correctly.
I'm using FragmentPagerAdapter with FragmentActivity to create swipe-able Fragments.
My first fragment in that pagerAdapter look like this.
public class MySummaryFragment extends CommonFragment implements OnPageChangeListener
{
private Context mContext;
private View mMyView;
LinearLayout mDetailLayout;
TextView mDateTxtView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("onCreateView() Market summary");
mMyView = inflater.inflate(R.layout.my_page_summary_fragment_layout, container,false);
mDetailLayout = (LinearLayout)mMyView.findViewById(R.id.SummaryDetailLayout);
mDateTxtView = (TextView) mMyView.findViewById(R.id.txtDate);
Account_Id = AccountDetails.getInstance(mContext).getClientCodes().get(0);
sendRequest(Account_Id);
return mMyView;
}
#Override
public void onPageSelected(int arg0) {
System.out.println("inside onPageScrollStateChanged()");
System.out.println("mMyView is null ? = "+(mMyView==null));
mDateTxtView = (TextView) mMyView.findViewById(R.id.txtMarketSummaryDate);
Account_Id = AccountDetails.getInstance(mContext).getClientCodes().get(0);
mDateTxtView.setText("");
sendRequest(Account_Id);
}
}
The problem here is I'm getting NullPointerException when swipe-out to 5-6 fragments and swiping back to first fragment.
When I try to debug, I found that
mMyView is null ? = true
Why so?
Please help me.
Here is my Fragment contains the FragmentPagerAdapter,
public class MyPageDetailViewFragment extends CommonFragment {
private View mView;
Context mContext;
OnPageChangeListener pageChangeListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.my_page_fragments, null);
mContext = getActivity();
setHasOptionsMenu(false);
setupSearchBarComponent();
PagerTabStrip pagerTabStrip = (PagerTabStrip)mView. findViewById(R.id.pager_title_strip);
pagerTabStrip.setDrawFullUnderline(true);
pagerTabStrip.setTabIndicatorColor(Color.BLACK);
/** Getting a reference to the ViewPager defined the layout file */
ViewPager pager = (ViewPager) mView.findViewById(R.id.pager);
/** Getting fragment manager */
FragmentManager fm = ((HomeScreenActivity)mContext).getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
final MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(0);
pageChangeListener = new OnPageChangeListener() {
#Override
public void onPageSelected(int selectedIndex) {
System.out.println("selectedIndex = "+selectedIndex);
Object page = pagerAdapter.getItem(selectedIndex);
if( page instanceof OnPageChangeListener){
((OnPageChangeListener) page).onPageSelected(selectedIndex);
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
pager.setOnPageChangeListener(pageChangeListener);
return mView;
// return super.onCreateView(inflater, container, savedInstanceState);
}
And here is my implementation MyFragmentPagerAdapter,
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
/** Constructor of the class */
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
/** This method will be invoked when a page is requested to create */
#Override
public Fragment getItem(int index) {
System.out.println("getItem = "+index);
Bundle data = new Bundle();
data.putInt("current_page", index + 1);
CommonFragment fragment = getFragment(index);
fragment.setArguments(data);
return fragment;
}
public CommonFragment getFragment(int index) {
CommonFragment fragment = null;
if(fragment == null){
if(index == 0){
fragment = new MySummaryFragment();
}else if(index == 1){
fragment = new FragmentOne();
}else if(index == 4){
fragment = new FragmentFour();
}else if(index == 5){
fragment = new FragmentFive();
}else{
fragment = new MyFragment();
}
}
return fragment;
}
/** Returns the number of pages */
#Override
public int getCount() {
return titles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
pagerAdapter.getItem(selectedIndex) actually creates a new instance of the fragment.
See this answer: https://stackoverflow.com/a/23843743/1271907
You have to keep a reference to the actual fragment.
It looks like you are calling the wrong method on the inflater.
Try to change this line:
mView = inflater.inflate(R.layout.my_page_fragments, null);
to:
mView = inflater.inflate(R.layout.my_page_fragments,container, null);