Dynamically load next fragment with ViewPager - android

I'm creating a demo app with the new android compatibility library. I want to show two listfragments with ViewPager. The first shows the root categories and the second shows the subcategories. After somebody clicks on root category the viewpager move to the subcategory, but it won't work, because always show the root category elements.
I spend few minutes with debug and I'm realised the ViewPager creates the second fragment after the first one.(I think the pager cache the next view or fragment.)
Is it possible to load the second fragment after onListItemClick?
Here is the code:
public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {
private static int mSelectedCategoryId;
private MyAdapter mMyAdapter;
private ViewPager mPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupPager();
}
private void setupPager() {
mPager = (ViewPager) findViewById(R.id.pager);
mMyAdapter = new MyAdapter(getSupportFragmentManager());
mPager.setAdapter(mMyAdapter);
}
#Override
public void onBookSelected(int categoryId) {
mSelectedCategoryId = categoryId;
if (mSelectedCategoryId == 0) {
mPager.setCurrentItem(1);
} else {
mPager.setCurrentItem(0);
}
}
public static class MyAdapter extends FragmentPagerAdapter {
private static final int NUMBER_OF_FRAGMENTS = 2;
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return BookListFragment.newInstance(mSelectedCategoryId);
}
#Override
public int getCount() {
return NUMBER_OF_FRAGMENTS;
}
}
}
public class BookListFragment extends ListFragment {
private static final String ARGUMENT_KEY = "categoryId";
private OnBookSelectedListener mOnBookSelectedListener;
private int mCategoryId;
public static BookListFragment newInstance(int categoryId) {
BookListFragment bookListFragment = new BookListFragment();
Bundle argument = new Bundle();
argument.putInt(ARGUMENT_KEY, categoryId);
bookListFragment.setArguments(argument);
return bookListFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCategoryId = getArguments() != null ? getArguments().getInt(ARGUMENT_KEY) : 0;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Books.getBooks(mCategoryId)));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView) tv).setText("Category :" + mCategoryId);
return v;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (mCategoryId == 0) {
mOnBookSelectedListener.onBookSelected(1);
} else {
mOnBookSelectedListener.onBookSelected(0);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOnBookSelectedListener = (OnBookSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + "Must Implement OnBookSelectedListener.");
}
}
public interface OnBookSelectedListener {
public void onBookSelected(int categoryId);
}
}
public class Books {
private static final String[] fruits = new String[] { "Apple", "Banana", "Orange" };
private static final String[] category = new String[] { "Lorem", "Dolor", "Ipsum" };
public static String[] getBooks(int categoryId) {
return categoryId == 0 ? category : fruits;
}
}

I solved the problem, I need to add List to the adapter and after that the getItem don't create new instance, only gets the item from the list.
This is the new code.
public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {
private MyAdapter mMyAdapter;
private ViewPager mPager;
private BookOnPageChangeListener mBookOnPageChangeListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupPager();
}
private void setupPager() {
mPager = (ViewPager) findViewById(R.id.pager);
mMyAdapter = new MyAdapter(getSupportFragmentManager());
mPager.setAdapter(mMyAdapter);
mBookOnPageChangeListener = new BookOnPageChangeListener();
mPager.setOnPageChangeListener(mBookOnPageChangeListener);
}
#Override
public void onBookSelected(int categoryId) {
mMyAdapter.addPage(categoryId);
mPager.setCurrentItem(mBookOnPageChangeListener.getCurrentPage() + 1);
}
public static class MyAdapter extends FragmentPagerAdapter {
private List<Fragment> pages;
public MyAdapter(FragmentManager fm) {
super(fm);
initPages();
}
/**
* Create the list and add the first ListFragment to the ViewPager.
*/
private void initPages() {
pages = new ArrayList<Fragment>();
addPage(0);
}
/**
* Add new BookListFragment to the ViewPager.
*
* #param categoryId
* - the category id
*/
public void addPage(int categoryId) {
pages.add(BookListFragment.newInstance(categoryId));
}
#Override
public Fragment getItem(int position) {
return pages.get(position);
}
#Override
public int getCount() {
return pages.size();
}
}
/**
* Get the current view position from the ViewPager.
*/
public static class BookOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
private int currentPage;
#Override
public void onPageSelected(int position) {
// current page from the actual position
currentPage = position;
}
public int getCurrentPage() {
return currentPage;
}
}
}

Have you tried using setOnItemClickListener()?

Related

how to add and remove hashmap key/value pair from view-pager fragment

I am using view-pager with fragment in my application. i want to add and remove any key/value from hash-map but it gives me null pointer exception. there are 5 elements in hash-map if i remove last key from map then it works fine. How to solve it.
Below is my problem code :
public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
public PagerAdapter adapter1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager1);
final HashMap<String,Integer> sliderDataList = new HashMap<String,Integer>();
sliderDataList.put("0",R.drawable.first);
sliderDataList.put("1",R.drawable.second);
sliderDataList.put("2",R.drawable.three);
sliderDataList.put("3",R.drawable.four);
sliderDataList.put("4",R.drawable.xiaomi);
adapter1 = new PagerAdapter(getSupportFragmentManager(), sliderDataList, MainActivity.this);
viewPager.setAdapter(adapter1);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
remove("3");
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void remove(String s){
adapter1.remove(s);
}
public class PagerAdapter extends FragmentStatePagerAdapter {
private HashMap<String, Integer> hMap;
private final Context context;
public PagerAdapter(FragmentManager fm, HashMap<String,Integer> hMap, Context context) {
super(fm);
this.hMap=hMap;
this.context=context;
}
#Override
public int getItemPosition (Object object)
{
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
return new SliderFragment(hMap,context,position);
}
#Override
public int getCount() {
return hMap.size();
}
public void remove(String s){
hMap.remove(s);
adapter1.notifyDataSetChanged();
}
}
#SuppressLint("ValidFragment")
public static class SliderFragment extends Fragment {
private HashMap<String, Integer> urls;
private int imageResourceId;
ImageView imageView;
private Context ctx;
public SliderFragment(HashMap<String,Integer> urls, Context c, int pos) {
this.urls = urls;
this.imageResourceId = pos;
this.ctx = c;
}
#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.content_main, container, false);
imageView = (ImageView) view.findViewById(R.id.img);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(urls.get(imageResourceId +""));
return view;
}
}
}
public void remove(String s){
if(sliderDataList.containskey("3"))
{
containskey.remove("3");
adapter1.notifydataSetChanged();
}
}
Try this:
Iterator<Map.Entry<String,String>> iter = TestMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,String> entry = iter.next();
if("Sample".equalsIgnoreCase(entry.getValue())){
iter.remove();
}
}
if you just want to remove the null pointer exception, then add this:
if (urls.get(imageResourceId + "") != null)
imageView.setImageResource(urls.get(imageResourceId + ""));

viewpager with images works but on back button images don't show

I have a viewpager with image fragments in it that works but on back was getting an error saying that there is no empty constructor. I made one but now my images don't show up because imageResourceId is null. I've tried a million things and can't figure it out.
public final class TestFragment extends Fragment {
String imageResourceId;
public TestFragment() {
}
public TestFragment(String cONTENT) {
imageResourceId = cONTENT;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView image = new ImageView(getActivity());
new DownloadImageTask((ImageView) image).execute(imageResourceId);
LinearLayout layout = new LinearLayout(getActivity());
layout.setGravity(Gravity.CENTER);
layout.addView(image);
return layout;
}
}
class TestFragmentAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
public String[] CONTENT;
private int mCount;
protected static final int[] ICONS = new int[] {
R.drawable.perm_group_calendar, R.drawable.perm_group_camera,
R.drawable.perm_group_device_alarms, R.drawable.perm_group_location };
public TestFragmentAdapter(FragmentManager fm, JSONArray photoData) {
super(fm);
// photoData = (JSONArray) userProfile.get("photos");
CONTENT = new String[photoData.length()];
mCount = photoData.length();
for (int i = 0; i < photoData.length(); i++) {
JSONObject mainPhoto;
try {
mainPhoto = photoData.getJSONObject(i);
CONTENT[i] = mainPhoto.getString("src_big");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
notifyDataSetChanged();
}
#Override
public Fragment getItem(int position) {
return new TestFragment(CONTENT[position]);
}
#Override
public int getCount() {
return mCount;
}
#Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
in the activity
mAdapter = new TestFragmentAdapter(
getSupportFragmentManager(), photoData);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (LinePageIndicator) findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
Android uses the empty constructor of a fragment to restore the fragment when there is a configuration change, that's why you can't modify it, and you can't override it because you get an error in eclipse. The best practice to pass arguments to a fragment, when instantiating it, is to use an static factory method:
public class TestFragment extends Fragment {
String imageResourceId;
public static TestFragment newInstance(String resource) {
TestFragment f = new TestFragment();
Bundle args = new Bundle();
args.putString("Resource", resource);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageResourceId = getArguments().getString("Resource");
}
}
To instanciate it you use the static method:
TestFragment fragment = TestFragment.newInstance("some string");

Android - Sending data from fragment to fragment using swipeview

Could be this is a dupe, but I've been looking for solutions and they always slightly differ from my problem.
So:
I'm currently creating an app that has 2 fragments that are swipeable. TaskGroupFragment shows a list and when you click on an item it wil slide to TasksFragment and show you a sublist. What I have to do now is send the id of the selected item from groups to tasks so I can get the sublist out of SQLite.
I know I'm supposed to communicate through the connected MainActivity and I'm already at the point that I've created an interface in TaskGroupsFragment and implemented this in the activity. Tried and tested and the activity receives the TaskGroupID.
The part where I'm stuck is getting this info in TasksFragment. Especially using swipeview makes this harder.
My code:
MainPagerAdapter:
public class MainPagerAdapter extends FragmentStatePagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0: return TaskGroupFragment.newInstance();
case 1: return TasksFragment.newInstance();
default: return TaskGroupFragment.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
TaskGroupActivity (sending fragment):
public class TaskGroupFragment extends ListFragment {
private DoItDataSource dataSource;
private List<TaskGroups> groups;
#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_task_group, container, false);
dataSource = new DoItDataSource(getActivity());
dataSource.open();
JSONContainer jsonContainer = dataSource.sqliteToContainer();
dataSource.close();
groups = jsonContainer.getTask_groups();
TaskGroupAdapter adapter = new TaskGroupAdapter(getActivity(), groups);
setListAdapter(adapter);
return view;
}
public static TaskGroupFragment newInstance() {
TaskGroupFragment tgf = new TaskGroupFragment();
return tgf;
}
public interface OnTaskGroupSelectedListener {
public void onTaskGroupSelected(String taskGroupId);
}
OnTaskGroupSelectedListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnTaskGroupSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " Interface not implemented in activity");
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
((MainActivity)getActivity()).setCurrentItem(1, true);
mListener.onTaskGroupSelected(groups.get(position).getId());
}
}
MainActivity:
public class MainActivity extends FragmentActivity implements
TaskGroupFragment.OnTaskGroupSelectedListener{
private SharedPreferences savedValues;
private DoItDataSource dataSource = new DoItDataSource(this);
private String identifier, user, domain;
private JSONContainer containerToday;
private JSONContainer containerTomorrow;
public ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedValues = getSharedPreferences("SavedValues", MODE_PRIVATE);
identifier = savedValues.getString("Identifier", "");
pager = (ViewPager) findViewById(R.id.activity_main_pager);
pager.setAdapter(new MainPagerAdapter(getSupportFragmentManager()));
if (identifier == null || identifier.equals("")) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("APP_ID", APP_ID);
startActivity(intent);
}
}
#Override
protected void onResume() {
super.onResume();
identifier = savedValues.getString("Identifier", "");
user = savedValues.getString("User", "");
domain = savedValues.getString("Domain", "");
boolean onBackPressed = savedValues.getBoolean("OnBackPressed", false);
//
// getting lists
//
}
private void resultHandling(String json, String day) {
if (day.equals("today")) {
Gson gson = new Gson();
containerToday = gson.fromJson(json, JSONContainer.class);
jsonToSQLite(containerToday, "Today");
} else if (day.equals("tomorrow")) {
Gson gson = new Gson();
containerTomorrow= gson.fromJson(json, JSONContainer.class);
jsonToSQLite(containerTomorrow, "Tomorrow");
}
}
String taskGroupId = "";
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
// Enter missing link here?
}
}
TaskFragment (receiving fragment):
public class TasksFragment extends ListFragment
implements OnClickListener {
private final static String TAG = "TaskItemFragment logging";
private DoItDataSource dataSource;
private List<Tasks> tasks;
#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_task_item, container, false);
Button backButton = (Button)
view.findViewById(R.id.fragment_task_item_bar_back_button);
dataSource = new DoItDataSource(getActivity());
dataSource.open();
tasks = dataSource.getTasks("204"); // 204 is a placeholder, TaskGroupId should be here
dataSource.close();
TasksAdapter adapter = new TasksAdapter(getActivity(), tasks);
setListAdapter(adapter);
backButton.setOnClickListener(this);
return view;
}
public static TasksFragment newInstance() {
TasksFragment tif = new TasksFragment();
return tif;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Clicked item " + position, Toast.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.fragment_task_item_bar_back_button:
((MainActivity)getActivity()).setCurrentItem(0, true);
break;
}
}
}
Solution
Thanks to Alireza! I had to make several changes to his proposed code, but in the end it helped me in finding the solution!
MainPageAdapter:
public class MainPagerAdapter extends FragmentStatePagerAdapter {
// ADDED
private String taskGroupId;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0: return TaskGroupFragment.newInstance();
// MODIFIED
case 1:
Bundle args = new Bundle();
logcat("before setBundle " + taskGroupId);
args.putString("taskGroupId",taskGroupId);
Fragment fragment = new TasksFragment();
fragment.setArguments(args);
return fragment;
default: return TaskGroupFragment.newInstance();
}
}
// ADDED
public void setTaskGroupId(String id){
this.taskGroupId = id;
}
#Override
public int getCount() {
return 2;
}
}
MainActivity:
public class MainActivity extends FragmentActivity implements
TaskGroupFragment.OnTaskGroupSelectedListener{
private SharedPreferences savedValues;
private DoItDataSource dataSource = new DoItDataSource(this);
private String identifier, user, domain;
private JSONContainer containerToday;
private JSONContainer containerTomorrow;
// ADDED
private MainPagerAdapter adapter;
public ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedValues = getSharedPreferences("SavedValues", MODE_PRIVATE);
identifier = savedValues.getString("Identifier", "");
// ADDED
adapter = new MainPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) findViewById(R.id.activity_main_pager);
// MODIFIED
pager.setAdapter(adapter);
if (identifier == null || identifier.equals("")) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("APP_ID", APP_ID);
startActivity(intent);
}
}
#Override
protected void onResume() {
super.onResume();
identifier = savedValues.getString("Identifier", "");
user = savedValues.getString("User", "");
domain = savedValues.getString("Domain", "");
boolean onBackPressed = savedValues.getBoolean("OnBackPressed", false);
//
// Getting lists
//
}
String taskGroupId = "";
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
// ADDED
adapter.setTaskGroupId(taskGroupId);
pager.setAdapter(adapter);
pager.setCurrentItem(1);
}
}
TaskFragment (receiving fragment):
public class TasksFragment extends ListFragment implements OnClickListener {
private final static String TAG = "TaskItemFragment logging";
private DoItDataSource dataSource;
private List<Tasks> tasks;
private String taskGroupId;
#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_task_item, container, false);
Button backButton = (Button) view.findViewById(R.id.fragment_task_item_bar_back_button);
dataSource = new DoItDataSource(getActivity());
// ADDED
Bundle bundle = getArguments();
taskGroupId = bundle.getString("taskGroupId");
// MODIFIED
dataSource.open();
tasks = dataSource.getTasks(taskGroupId);
dataSource.close();
TasksAdapter adapter = new TasksAdapter(getActivity(), tasks);
setListAdapter(adapter);
backButton.setOnClickListener(this);
return view;
}
// CAN BE REMOVED?
//public static TasksFragment newInstance() {
// TasksFragment tif = new TasksFragment();
// return tif;
//}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Clicked item " + position, Toast.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.fragment_task_item_bar_back_button:
((MainActivity)getActivity()).setCurrentItem(0, true);
break;
}
}
}
Please note that I'm using taskGroupId as a String, not an int.
First you need to make sure your adapter knows about taskGroupID. just add a variable and a public method to your adapter.
public class MainPagerAdapter extends FragmentStatePagerAdapter {
private int taskGroupId;
public void setTaskGroupId(int id){
this.taskGroupId = id;
}
}
then store a reference to your adapter in your activity. Now simply call this method whenever GroupId changes
#Override
public void onTaskGroupSelected(String taskGroupId) {
this.taskGroupId = taskGroupId;
adapter.setTastGroupId = taskGroupId; //data needed to initialize fragment.
adapter.setCurrentItem(1); //going to TasksFragment page
}
then you need to put some argumants before starting your fragment.
#Override
public Fragment getItem(int i) {
//this code is only for case 1:
Bundle args = new Bundle();
args.putInt("taskGroupId",taskGroupId);
Fragment fragment = new TasksFragment();
fragment.setArguments(args);
return fragment;
}
and lastly use this data in your TaskFragment to show the right content.

need help to fix code for getting current view in viewpager

Need help to fix a code I saw in a https://stackoverflow.com/a/9275732/1938357. The solution I need is get the current view onany page in my viewpager based application
Below is the code for reference
public View getCurrentView(ViewPager pager) {
for (int i = 0; i < pager.getChildCount(); i++) {
View child = pager.getChildAt(i);
if (child.getX() <= pager.getScrollX() + pager.getWidth()
&& child.getX() + child.getWidth() >= pager.getScrollX() + pager.getWidth()) {
return child;
}
}
return getChildAt(0);
I am trying to access the current view in the view pager and used the code above. It works fine when I scroll forwards. But when I scroll backwards then after 2 backward scrolls this stops working.
Public class myActivity extends FragmentActivity
//Variable declarations
protected void onCreate(Bundle savedInstanceState) {
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
View CurrView;
OnPageChangeListener pageChangelistener = new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
doTextViewChnges();//access the text view and update it based on pageSelected
---THIS IS WHERE I AM STUCK IN TRYING TO GET THE TEXTVIEW IN MY CURRENT FRAGMWNT/VIEW-------
}
mPager.setOnPageChangeListener(pageChangelistener);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
return ScreenSlidePageFragment.create(position, <other parameters I want to pass>);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
And below is my ScreenSlidePageFragment class
public class ScreenSlidePageFragment extends android.support.v4.app.Fragment {
public static final String ARG_PAGE = "pagenumber";
public static final String ARG_PAGEARRAY = "pages";
private int mPageNumber;
//Declare other variables
#SuppressLint("NewApi")
public static ScreenSlidePageFragment create(int pageNumber, String[] pages, int bookmarkPageNumber, String storyName, int linesInOnePage) {
ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
args.putStringArray(ARG_PAGEARRAY, pages);
fragment.setArguments(args);
return fragment;
}
#SuppressLint("NewApi")
public ScreenSlidePageFragment() {
}
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
pages = getArguments().getStringArray(ARG_PAGEARRAY);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = (ViewGroup) inflater
.inflate(R.layout.activity_story, container, false);
//load layout with all components filled up for that page
loadView(rootView);
return rootView;
}
public int getPageNumber() {
return mPageNumber;
}
It is very hard to discuss in comments with example of code.
As I see in grepcode FragmentStatePagerAdapter.setPrimaryItem(), receive object as android.support.v4.app.Fragment. But you are receive ClassCastException when trying to cast object as Fragment. Can you check your casting: do you really cast object in android.support.v4.app.Fragment not in android.app.Fragment? If all right, add your exception message to your question, please.
UPDATE:
If your ScreenSlidePagerAdapter has method getCurrentView(), then your method 'getCurrentView()' can work like this:
public View getCurrentView(ViewPager pager) {
return ((ScreenSlidePagerAdapter) pager.getAdapter()).getCurrentView();
}
And method getCurrentView() of your ScreenSlidePagerAdapter:
public View getCurrentView() {
return currView;
}
UPDATE 2:
I've made some modification with your code:
Your Activity with private Adapter:
public class myActivity extends FragmentActivity implements ISelectItemListener {
// Your variable declarations and methods
#Override
protected void onCreate(Bundle savedInstanceState) {
final ViewPager pager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
pager.setAdapter(mPagerAdapter);
pager.setOnPageChangeListener(
new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
final ScreenSlidePageFragment fragment = mPagerAdapter.getFragment(pageSelected);
if (fragment != null) {
fragment.doTextViewChnges();
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
});
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
//Your variable declarations
private final ScreenSlidePageFragment[] mFragments;
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
mFragments = new ScreenSlidePageFragment[NUM_PAGES];
}
#Override
public int getCount() {
return NUM_PAGES;
}
// It will create new ScreenSlidePageFragment by position if it's not exsist
#Override
public android.support.v4.app.Fragment getItem(int position) {
if (getFragment(position) == null) {
mFragments[position] = ScreenSlidePageFragment.create(position, <other parameters I want to pass>);
}
return getFragment(position);
}
// It will give you ScreenSlidePageFragment if it's exists, or null
public ScreenSlidePageFragment getFragment(int position) {
return mFragments[position];
}
}
}
Your Fragment:
public class ScreenSlidePageFragment extends Fragment {
//Your variables and methods
public static ScreenSlidePageFragment create(int pageNumber, String[] pages, int bookmarkPageNumber, String storyName, int linesInOnePage) {
final Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
args.putStringArray(ARG_PAGEARRAY, pages);
final ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
pages = getArguments().getStringArray(ARG_PAGEARRAY);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = (ViewGroup) inflater.inflate(R.layout.activity_story, container, false);
loadView(rootView);
return rootView;
}
public int getPageNumber() {
return mPageNumber;
}
// Let's keep logic of modifications in fragment
public void doTextViewChnges() {
final View view = getView();
// do what you want with your View and his children
}
}

Replacing a fragment from ViewPager android

SCENARIO
I am creating a fragment structure with dynamic fragment creations. Each item in the fragment creates the next fragment. In the scenario I am storing all these fragments in the ArrayList of fragments so that I can easily replace the created fragment.
PROBLEM
Now I am replacing a fragment from the ArrayList by removing the fragment from a particular index and adding the new one. But when I try to get the fragment from that particular index it returns me the old data without calling the getItem function of the FragmentStateAdapter again.
Here is my Main class.
MainActivity.java
public class MainActivity extends FragmentActivity implements
onPageSelectedListener {
SectionsPagerAdapter mSectionsPagerAdapter;
static int current, listItem;
static String TAG = "MainActivity";
static ViewPager mViewPager;
static ArrayList<Fragment> FragmentList;
static ArrayList<String> titles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init(){
FragmentList = new ArrayList<Fragment>();
titles = new ArrayList<String>();
mViewPager = (ViewPager) findViewById(R.id.pager);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public void addPage(int position, String title, String file, String tag) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putString(DummySectionFragment.ARG_FILE_NAME, file);
args.putString(DummySectionFragment.ARG_FILE_TAG, tag);
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
titles.add(position, title);
FragmentList.add(position, fragment);
}
public void NextScreen(int position, String title, String file, String tagname) {
if(FragmentList.size()>(position-1)){
for(int i=position; i<FragmentList.size(); i++){
FragmentList.remove(i);
}
}
addPage(position, title, file, tagname);
mViewPager.setCurrentItem(position);
}
public static class PageChanger extends
ViewPager.SimpleOnPageChangeListener {
private int currentPage;
#Override
public void onPageSelected(int position) {
currentPage = position;
}
public int getCurrentScreen() {
return currentPage;
}
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
addPage(0, "Main Fragment", "test.xml", "mytag");
}
#Override
public Fragment getItem(int position) {
return FragmentList.get(position);
}
#Override
public int getCount() {
return FragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "Main Categories";
}
getItem(position);
return titles.get(position);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
public static class DummySectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_FILE_NAME = "file_name";
public static final String ARG_FILE_TAG = "tag_name";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
savedInstanceState = this.getArguments();
ListView parent_list = new ListView(getActivity());
String file_name = savedInstanceState.getString(ARG_FILE_NAME);
String tag_name = savedInstanceState.getString(ARG_FILE_TAG);
int current_level = savedInstanceState.getInt(ARG_SECTION_NUMBER);
PullParser pull = new PullParser(getActivity());
pull.pullXml(file_name, tag_name);
parent_list.setAdapter(new ListAdapter(getActivity(),
PullParser.Xml_Tag_Info, current_level));
return parent_list;
}
}
#Override
public void onPageSelected(int pageno) {
current = pageno;
}
}
I have found the answer just to reinstantiate the adapter after making the necessary changes. The edited code is here.
MainActivity.java
public class MainActivity extends FragmentActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
static int current, listItem;
static String TAG = "MainActivity";
static boolean flag = false;
/**
* The {#link ViewPager} that will host the section contents.
*/
static ViewPager mViewPager;
static ArrayList<DummySectionFragment> FragmentList;
static ArrayList<String> titles;
static FragmentManager fragManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init() {
FragmentList = new ArrayList<DummySectionFragment>();
titles = new ArrayList<String>();
mViewPager = (ViewPager) findViewById(R.id.pager);
fragManager = getSupportFragmentManager();
mSectionsPagerAdapter = new SectionsPagerAdapter(fragManager);
mViewPager.setAdapter(mSectionsPagerAdapter);
titles.add(0, "Main Categories");
}
public void addPage(final int position, String file, String tag) {
DummySectionFragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putString(DummySectionFragment.ARG_FILE_NAME, file);
args.putString(DummySectionFragment.ARG_FILE_TAG, tag);
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
try {
FragmentList.set(position, fragment);
} catch (IndexOutOfBoundsException e) {
FragmentList.add(position, fragment);
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroyFragment(int position) {
SectionsPagerAdapter pagerAdapter = (SectionsPagerAdapter) mViewPager
.getAdapter();
pagerAdapter.destroyItem(mViewPager, position,
FragmentList.get(position));
pagerAdapter.notifyDataSetChanged();
}
public void addFragment(int position, Object object) {
SectionsPagerAdapter pagerAdapter = (SectionsPagerAdapter) mViewPager
.getAdapter();
pagerAdapter.notifyDataSetChanged();
}
public void NextScreen(int position, String title, String file,
String tagname) {
if (FragmentList.size() > position - 1) {
for (int i = FragmentList.size() - 1; i > position; i--) {
titles.remove(i);
FragmentList.remove(i);
}
titles.trimToSize();
FragmentList.trimToSize();
}
titles.add(position, title);
addPage(position, file, tagname);
mViewPager.setAdapter(new SectionsPagerAdapter(fragManager));
mViewPager.setCurrentItem(position);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
addPage(0, "catlist.xml", "pid-0");
}
#Override
public Fragment getItem(int position) {
return FragmentList.get(position);
}
public void setId() {
}
#Override
public int getCount() {
return FragmentList.size();
}
#Override
public int getItemPosition(Object object) {
return FragmentList.indexOf(object);
}
#Override
public CharSequence getPageTitle(int position) {
Log.v("titlePosition", position + "");
return titles.get(position);
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static ArrayList<Xml_Item_Data> resultList = new ArrayList<Xml_Item_Data>();
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_FILE_NAME = "file_name";
public static final String ARG_FILE_TAG = "tag_name";
ListView parent_list;
public static Bundle setValues;
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
savedInstanceState = this.getArguments();
parent_list = new ListView(getActivity());
String file_name = savedInstanceState.getString(ARG_FILE_NAME);
String tag_name = savedInstanceState.getString(ARG_FILE_TAG);
int current_level = savedInstanceState.getInt(ARG_SECTION_NUMBER);
PullParser pull = new PullParser(getActivity());
pull.pullXml(file_name, tag_name);
ListAdapter list_Creator = new ListAdapter(getActivity(),
PullParser.Xml_Tag_Info, current_level);
parent_list.setAdapter(list_Creator);
return parent_list;
}
}
}
I think you can try return POSITION_NONE in your getItemPosition() method. Like here: How to force ViewPager to re-instantiate its items

Categories

Resources