I'm trying to use a ListFragment with a ViewPager using the FragmentPagerAdapter. The pager consists of two instances of the ListFragment. The ViewPager control works and allows me to swipe between the fragments however the same ListFragment appears in both pages. It seems that getItem() method of the ViewPager creates two different instances of the ListFragment but it displays only the second instance of it for both pages. Here is a code:
// FragmentPagerAdapter
private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
Log.i("Page: ", index + "");
return PageFragment.newInstance(pages.get(index));
// pages is an ArrayList<ArrayList<Restaurant>> pages
}
#Override
public int getCount() {
return numberOfPages;
}
}
// ListFragment
public class PageFragment extends ListFragment {
private static ArrayList<Restaurant> restaurantsList;
public static PageFragment newInstance(ArrayList<Restaurant> restaurantsList) {
PageFragment pageFragment = new PageFragment();
pageFragment.setRestaurantsList(restaurantsList);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
setListAdapter(new RestaurantArrayAdapter(getActivity().getBaseContext(), getRestaurantsList()) );
return view;
}
private void setRestaurantsList(ArrayList<Restaurant> list)
{
restaurantsList = list;
}
private ArrayList<Restaurant> getRestaurantsList()
{
return this.restaurantsList;
}
}
Well mate,
The problem is you've declared you array member as "Static",
private static ArrayList<Restaurant> restaurantsList;
Lose the static and you should be fine.
Related
I am trying to refresh the current fragment in the tabbed layout of my viewpager. I have one fragment (UserProgressFragment) that creates the ViewPager and sets the adapter (UserProgressAdapter) along with creating tabbed layout.
In my UserProgressAdapter, in the getItem() method I am returning two other fragments, (UserWeightTrackerFragment and UserCalorieCounterFragment) based on which tab i am on.
My issue is how do i refresh the fragment and update its content/view from the UserCalorieCounterFragment on a button click, because access to the viewpager and adapter are set in the UserProgressFragment? I have considered notifyDataChange for the adapter but i dont know how to call this from this class as it is set up on the UserProgressFragment class. The purpose of wanting to refresh this page is to update a specific view which is a chart, if context is needed.
I have attached the code below:
UserProgressFragment
public class UserProgressFragment extends Fragment{
public static UserProgressFragment newInstance() {
return new UserProgressFragment();
}
public UserProgressFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_progress, container, false);
ViewPager viewPager = view.findViewById(R.id.progress_viewpager);
viewPager.setAdapter(new UserProgressTabsAdapter(getChildFragmentManager()));
TabLayout tabLayout = view.findViewById(R.id.progress_sliding_tabs);
tabLayout.setupWithViewPager(viewPager, true);
return view;
}
}
UserProgressTabsAdapter
public class UserProgressTabsAdapter extends FragmentStatePagerAdapter {
private static final int PAGE_COUNT = 2;
private String tabTitles[] = new String[]{"Weight Tracker", "Calorie Counter"};
public UserProgressTabsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return UserWeightTrackerFragment.newInstance(position);
case 1:
return UserCalorieCounterFragment.newInstance(position + 1);
}
return null;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
UserCalorieCounterFragment (need to refresh this one)
public class UserCalorieCounterFragment extends Fragment implements View.OnClickListener, AdapterView.OnItemSelectedListener {
public static final String ARG_PAGE = "ARG_PAGE";
public static UserCalorieCounterFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
UserCalorieCounterFragment fragment = new UserCalorieCounterFragment();
fragment.setArguments(args);
return fragment;
}
public UserCalorieCounterFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mPage = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_calorie_counter, container, false);
Button mAddCalories = view.findViewById(R.id.btn_add_calorie);
mAddCalories.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_add_calorie:
//REFRESH/UPDATE HERE
break;
}
}
You can create a public method in your fragment which contains the view pager which will contain the notifyDataSetChanged() function. And in the view pager fragment/item, you can call getParentFragment() and type cast it to your parent/first fragment and access that public method to notifyDataSetChanged().
I have a ViewPager that I want to add Fragments to.
The ViewPager is viewed correctly on the screen but unfortunately it does not hold any content.
I have seen the suggestion in some posts to replace
getSupportFragmentManager()
with
getChildFragmentManager()
But I need the ActionBar. Unfortunately the ChildFragmentmanager is not available in the AppCompatActivity.
While debugging I have realized that the Fragment's onCreateView() method is called and it returns a layout.
Question: How can I make the Fragments visible? And were is the main difference from my code to that sample ?
Activity:
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager mViewPager;
private List<Location> locationList = new ArrayList<>();
private locationsBaseHandler db;
private CustomPagerAdapter mAdapter;
private Location mLocation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
locationList.add(someData);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mAdapter = new CustomPagerAdapter(this, getSupportFragmentManager(), locationList);
mViewPager.setAdapter(mAdapter);
}
}
Pager Adapter:
public class CustomPagerAdapter extends FragmentPagerAdapter {
private Context mContext;
private List<Location> locationList = new ArrayList<>();
public CustomPagerAdapter(Context mContext, FragmentManager fm, List<Location> locationList) {
super(fm);
this.locationList.addAll(locationList);
this.mContext = mContext;
}
#Override
public Fragment getItem(int position) {
return LocationFragment.newInstance(position);
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
}
Fragment:
public class LocationFragment extends Fragment {
private static final String ARG_LAYOUT_ID = "page_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_location, container, false);
return layout;
}
public static LocationFragment newInstance(int selectedIdForIndex) {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
args.putInt(ARG_LAYOUT_ID, selectedIdForIndex);
fragment.setArguments(args);
return fragment;
}
public int getPageNumber() {
return getArguments().getInt(ARG_LAYOUT_ID);
}
}
Try to remove the method isViewFromObject in CustomPagerAdapter.
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
We can see this comment to isViewFromObject:
Determines whether a page View is associated with a specific key object
as returned by {#link #instantiateItem(ViewGroup, int)}. This method is
required for a PagerAdapter to function properly.
I am using ViewPager in my activity and it only has two fragments, both implemented in similar structure as follow, so there should always be a fragment returned when getInstanced is called:
public class ListReminderFragment extends Fragment {
private View rootView;
private static ListReminderFragment listReminderFragment;
public static ListReminderFragment getInstance() {
if(listReminderFragment != null)
return listReminderFragment;
else {
listReminderFragment = new ListReminderFragment();
return listReminderFragment;
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.content_main_screen, container, true);
return rootView;
}
#Nullable
#Override
public View getView() {
return rootView;
}
}
This is my adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return ListReminderFragment.getInstance(); // temporary
}
#Override
public int getCount() {
return 2;
}
}
And I am initialising my ViewPager as below, in OnCreate() in the activity that has the ViewPager:
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager) findViewById(R.id.main_view_pager);
viewPager.setAdapter(viewPagerAdapter);
But when I call viewPager.getChildAt(), viewPagerAdapter.getItem(0).getView(), they both return null,
when I call viewPager.getChildCount(), it returns 0 instead of 2.
How should I access the views in side the fragment in ViewPager?
I am trying to swipe item(from listview) in my detail activity using viewpager.
I have 20 items in my listview (data parsed from json) Instead of swiping the next/previous item , It's only the same item that I swipe (20 times).
here is my DetailActivity.
public class DetailsActivity extends FragmentActivity {
Article feed;
int pos;
private DescAdapter adapter;
private ViewPager pager;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.item_details);
pos = getIntent().getExtras().getInt("pos");
adapter = new DescAdapter(getSupportFragmentManager());
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
pager.setCurrentItem(pos);
}
public class DescAdapter extends FragmentStatePagerAdapter {
public DescAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 20;
}
public Fragment getItem(int position) {
return DetailFragment.newInstance(position);
}
}
And my detailFragment
public class DetailFragment extends Fragment {
static DetailFragment newInstance(int position) {
DetailFragment f = new DetailFragment();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.detail_fragment, container, false);
String displaytitle= getActivity().getIntent().getStringExtra("title");
TextView titleF = (TextView)view.findViewById(R.id.title);
titleF.setText(displaytitle);
...
return view;
}
What am I doing wrong?
You are not using the correct argument:
You send the argument "pos2" but you retrieve the argument "title".
#Override
public Fragment getItem(int position) {
DetailFragment frag = new DetailFragment();
Bundle bundle = new Bundle();
bundle.putInt("fPos",position);
frag.setArguments(bundle);
return frag;
}
I am using View pager to create a swipe view effect
Now i want to implement different fragments on same activity fragments are different layout which are displayed according to the condition.
I am stuck on how to create pagerAdapter and how to create fragment class.
Code:
public class mFragment extends Fragment{
Context mContext;
public mFragment(Context context){
mContext = context;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, ActivityScreen.mViewPager,false);
}
}
public class mPagerAdapter extends FragmentPagerAdapter
{
int i=-1;
public mPagerAdapter(FragmentManager fm)
{
super(fm);
mViewPager.removeAllViews();
}
#Override
public int getCount()
{
return data.size();
}
#Override
public Fragment getItem(int pos) {
return new mFragment(Context ctx);
}
}
Please help me on this
Override #instantiateItem method and return the fragments to update in the view
use this link
will be helpful m i think
in your FragmentActivity add an adapter for FragmentPagerAdapter then
#Override Fragment getItem and add Fragments to it accourding to requirement