Dynamically assign the final NUM_PAGES of viewpager - android

I got the screenslider to work from the android Screenslider,
put a webview in and got it to load the urls i assign to it.
It works fine but now i'd like to control the private static final int NUM_PAGES = 5;
and dynamically change it from a sqlite database numrowcount when i move to this activity.
I tried wrappers and then some but it will crash everytime.
My knowledge of java is somewhat limited elas.
Now i know this works in the oncreate
Bundle bundle = new Bundle();
bundle.putString("urlData", urlData);
ScreenSlidePageFragment fragobj = new ScreenSlidePageFragment();
fragobj.setArguments(bundle);
So i assign the url thats being used to get content within the fragment.
Now how do i control the private static final int NUM_PAGES = 5,
and reassign it to whatever number i want or get from the database?
I just cant get why this is such a difficult thing to create
or find on the web.
Seems to me it should be a non final static number.
I know i am totaly not getting it, but someone does ;)
Anybody any idea?
this is the code:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
...
public class ScreenSlidePagerActivity extends FragmentActivity {
/**
* The number of pages (wizard steps) to show in this demo.
*/
private static final int NUM_PAGES = 5;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
/**
* A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
* sequence.
*/
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new ScreenSlidePageFragment();
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}

Mm i turn out to be easy just make it non final and slip in a variable (int count) with the constructor.
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public int NUM_COUNT;
#Override
public int getCount() {
return NUM_COUNT;
}
public ScreenSlidePagerAdapter(FragmentManager fm,int count) {
super(fm);
this.NUM_COUNT = count;
}
#Override
public Fragment getItem(int position) {
return ScreenSlidePageFragment.create(position);
}
}

Related

How to add Fragments in ViewPager from getView

Can any one help me , How to add ViewPager using FragmentStatePageAdapter in getView.
I am using https://github.com/Diolor/Swipecards library . My requirement is to add viewpager at every card from using FrgamentStatePageAdapter. But after implementing ViewPager only first item contains ViewPager other cards is not accepting Viewpager .
Please suggest.
In my case am not using any library, this is how I use it.
private static final int NUM_PAGES = NUMBER OF PAGES I NEED;
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return ScreenSlidePageFragment.create(position);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
The NUM_PAGES determines the number of pages we need. Please check your code for that.
In the Adapter,
public static ScreenSlidePageFragment create(int pageNumber) {
ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
return fragment;
}
public ScreenSlidePageFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
}

Unable to Delete a fragment from ViewPager

My goal is to delete a fragment from a ViewPager upon user button click.
Populating the ViewPager works fine, but when I try to delete it, I get an error indicating a null reference. I incorporated Remove Fragment Page from ViewPager in Android
In my fragment to be deleted I have:
Button delete = (Button) getActivity().findViewById(R.id.dont_show_button_1);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.deletePerson(count); // SQLiteDatabase, works fine
displayActivity.removeCurrentFragment(count-1);
}
});
DisplayActivity is as follows:
public class DisplayActivity extends FragmentActivity {
ViewPager viewPager;
PagerAdapter pagerAdapter;
String TAG = "DisplayActivity";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.db_layout);
viewPager = (ViewPager) findViewById(R.id.pager);
pagerAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
}
public void removeCurrentFragment(int position){
pagerAdapter.fragmentArrayList.remove(position);
pagerAdapter.notifyChangeInPosition(1);
pagerAdapter.notifyDataSetChanged();
Log.e(TAG, "in removeCurrentFragment");
}
}
PagerAdapter
public class PagerAdapter extends FragmentPagerAdapter {
long baseId = 0;
public static List<Fragment> fragmentArrayList = new ArrayList<Fragment>();
public PagerAdapter(FragmentManager fm){
super(fm);
fragmentArrayList.add(new FragmentOne());
fragmentArrayList.add(new FragmentTwo());
fragmentArrayList.add(new FragmentThree());
}
#Override
public Fragment getItem(int position) {
return fragmentArrayList.get(position);
}
#Override
public int getCount() {
return fragmentArrayList.size();
}
#Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
#Override
public long getItemId(int position) {
// give an ID different from position when position has been changed
return baseId + position;
}
/**
* Notify that the position of a fragment has been changed.
* Create a new ID for each position to force recreation of the fragment
* #param n number of items which have been changed
*/
public void notifyChangeInPosition(int n) {
// shift the ID returned by getItemId outside the range of all previous fragments
baseId += getCount() + n;
}
}
This is the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void .DisplayActivity.removeCurrentFragment(int)' on a null object reference
Triggered from the fragment
Edit:
public class FragmentOne extends Fragment {
DatabaseHelper db;
WebView mWebView;
DisplayActivity displayActivity;
int count = 1;
This is how I get reference from displayActivity, is this the wrong way to get a reference of it?
if (count > 0) {
displayActivity.removeCurrentFragment(count - 1);
}

IllegalStateException: Can't change tag of fragment ViewPager

My ViewPager will delete a fragment upon button click. But when I click delete, I get "canot change tag" error. Browsing through other similar questions, it was either a problem with the getItem, or getCount in the PagerAdapter, which I think my implementation is fine. Please advice.
This is the fragment to be deleted
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
displayActivity = (DisplayActivity) getActivity();
initView();
}
Button delete = (Button) getActivity().findViewById(R.id.dont_show_button_1);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayActivity.removeCurrentFragment(count-1);
}
});
My PagerAdapter is
public class PagerAdapter extends FragmentPagerAdapter {
long baseId = 0;
public static List<Fragment> fragmentArrayList = new ArrayList<Fragment>();
public PagerAdapter(FragmentManager fm){
super(fm);
fragmentArrayList.add(new FragmentOne());
fragmentArrayList.add(new FragmentTwo());
fragmentArrayList.add(new FragmentThree());
}
#Override
public Fragment getItem(int position) {
return fragmentArrayList.get(position);
}
#Override
public int getCount() {
return fragmentArrayList.size();
}
#Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
#Override
public long getItemId(int position) {
// give an ID different from position when position has been changed
return baseId + position;
}
/**
* Notify that the position of a fragment has been changed.
* Create a new ID for each position to force recreation of the fragment
* #param n number of items which have been changed
*/
public void notifyChangeInPosition(int n) {
// shift the ID returned by getItemId outside the range of all previous fragments
baseId += getCount() + n;
}
}
This is the activity that hosts the ViewPager
public class DisplayActivity extends FragmentActivity {
ViewPager viewPager;
PagerAdapter pagerAdapter;
String TAG = "DisplayActivity";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.db_layout);
viewPager = (ViewPager) findViewById(R.id.pager);
pagerAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
}
public void removeCurrentFragment(int position){
pagerAdapter.fragmentArrayList.remove(position);
pagerAdapter.notifyChangeInPosition(1);
pagerAdapter.notifyDataSetChanged();
Log.e(TAG, "in removeCurrentFragment");
}
I'm getting the error:
IllegalStateException: Can't change tag of fragment FragmentTwo{170c98f1 #1 id=0x7f0c006d android:switcher:2131492973:1}: was android:switcher:2131492973:1 now android:switcher:2131492973:3
The problem was with
public class PagerAdapter extends FragmentPagerAdapter
Changing it to
public class PagerAdapter extends FragmentStatePagerAdapter
enabled correct deletion.
This can be attributed to "FragmentStatePagerAdapter disposes of views that fall outside the current and traversable views."
As suggested to this post
Remove Fragment Page from ViewPager in Android
By Looking at your code i think your count value may be wrong.
Button delete = (Button) getActivity().findViewById(R.id.dont_show_button_1);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// here
displayActivity.removeCurrentFragment(count-1);
//change to
displayActivity.removeCurrentFragment(adapter.getCount()-1);
}
});
Hope it helps.Please post your whole code like where you getting the value of count variable. Post whole Code if Solution Does not Solve Your Problem .
Refer here for example:- https://androidruler.wordpress.com/2016/02/22/working-with-viewpager-as-a-images-slider/

Changing pagetitle in Android Viewpager

I have a ViewPager in which I am using the getPageTitle method to get the title of the current page.
Here is the Adapter code:
#Override
public Fragment getItem(int i) {
details = productData.get(i);
Fragment fragment = new ProductViewFragment();
Bundle args = new Bundle();
args.putInt(ProductViewFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return productData.size();
}
public CharSequence getPageTitle(int position)
{
return (position+1)+" of "+myData.size();
}
Now I would like to update the page titles of the previous and next fragments. I want to name them as "previous" and "next". And it should be updated dynamically on subsequent pages also.
I am able to get the current page title number. For example, when I view the 5th fragment, the current fragment will show the title properly. And at both the corners of the ViewPager it shows the previous page title number on the left and next page title number on the right. Now, I want to have the page titles as "previous" on the left and "next" on the right, similar to the Gmail app and how it shows the mail count in the ViewPager.
The main thing I want to know is how can I access/modify the page title data of the next/previous fragments from the current fragment like they do in the Gmail app?
I based this on the samples that come with the ViewPagerIndicator.
You basically listen for when the page changes and tell the adapter to display a different page title depending on the current position.
If you have those samples working and you just replace those two files, then try the sample Titles->Default and it works fine for me...
Changed the code for TestFragmentAdapter like this:
package com.viewpagerindicator.sample;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.viewpagerindicator.IconPagerAdapter;
class TestFragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
protected static final String[] CONTENT = new String[] { "This", "Is", "A", "Test", };
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
};
private int mCount = CONTENT.length;
// CHANGE STARTS HERE
private int current_position=0;
public void set_current_position(int i) {
current_position = i;
}
// CHANGE ENDS HERE
public TestFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
}
#Override
public int getCount() {
return mCount;
}
#Override
public CharSequence getPageTitle(int position) {
// CHANGE STARTS HERE
if (position == current_position-1) {
return "Previous";
} else if (position == current_position+1) {
return "Next";
}
// CHANGE ENDS HERE
return TestFragmentAdapter.CONTENT[position % CONTENT.length];
}
#Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
the code for SampleTitlesDefault looks like this (added the OnPageChangeListener)
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.TitlePageIndicator;
// CHANGE ADDED implements.... HERE
public class SampleTitlesDefault extends BaseSampleActivity implements ViewPager.OnPageChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_titles);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
// CHANGE STARTS HERE
mIndicator.setOnPageChangeListener(this);
// CHANGE ENDS HERE
}
// CHANGE STARTS HERE
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
mPager = (ViewPager)findViewById(R.id.pager);
((TestFragmentAdapter)mPager.getAdapter()).set_current_position(i);
}
#Override
public void onPageScrollStateChanged(int i) {
}
// CHANGE ENDS HERE
}

Viewpager adapter not changing views

i have an activity with actionbarsherlock TabsNavigation (3 tabs) and when I press a tab i change the viewpager adapter of the corresponding fragment. it is working fine, the thing is that when I click on another tab besides the first created, the first page is always the one of that first tab. I tried to put invalidate() before changing the adapter, but it isnt working. anyone has any idea? here is the code:
public class Tabsteste2 extends SherlockFragmentActivity implements TabListener {
static AdapterOpiniao mOdapter;
static AdapterDados mDdapter;
static AdapterFoto mFdapter;
Bundle extras;
JSONParser jsonParser = new JSONParser();
SharedPreferences mPrefs;
static ViewPager mPager;
static int countopiniao;
static int countdados;
static int countfoto;
JSONArray perguntas = null;
PageIndicator mIndicator;
static ArrayList<HashMap<String, String>> opiniaolist;
static ArrayList<HashMap<String, String>> dadoslist;
static ArrayList<HashMap<String, String>> fotolist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabsteste2);
opiniaolist = new ArrayList<HashMap<String, String>>();
dadoslist = new ArrayList<HashMap<String, String>>();
fotolist = new ArrayList<HashMap<String, String>>();
mPager = (ViewPager)findViewById(R.id.pager);
extras = getIntent().getExtras();
Boolean opiniaoflag = extras.getBoolean("opiniaoflag");
Boolean dadosflag = extras.getBoolean("dadosflag");
Boolean fotoflag = extras.getBoolean("fotoflag");
countdados= extras.getInt("countdados");
countopiniao=extras.getInt("countopiniao");
countfoto=extras.getInt("countfoto");
mPrefs = getSharedPreferences("mPrefs1",MODE_PRIVATE);
Log.d("countdados",""+countdados);
Log.d("countfoto",""+countfoto);
Log.d("countopiniao",""+countopiniao);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
if(opiniaoflag==true){
ActionBar.Tab opiniaotab = getSupportActionBar().newTab();
opiniaotab.setText("OpiniĆ£o");
opiniaotab.setTag("op");
opiniaotab.setTabListener(this);
mOdapter = new AdapterOpiniao(getSupportFragmentManager());
Log.d("Opiniao",""+opiniaotab.getTag());
getSupportActionBar().addTab(opiniaotab);
}if(dadosflag == true){
ActionBar.Tab dadostab = getSupportActionBar().newTab();
dadostab.setText("Dados");
dadostab.setTag("dd");
mDdapter = new AdapterDados(getSupportFragmentManager());
dadostab.setTabListener(this);
Log.d("Dados",""+dadostab.getTag());
getSupportActionBar().addTab(dadostab);
}
// mDdapter = new AdapterDados(getSupportFragmentManager());
if(fotoflag==true){
ActionBar.Tab fotostab = getSupportActionBar().newTab();
fotostab.setText("Fotos");
fotostab.setTag("ft");
mFdapter = new AdapterFoto(getSupportFragmentManager());
fotostab.setTabListener(this);
Log.d("Foto",""+fotostab.getTag());
getSupportActionBar().addTab(fotostab);
}
new getpergunta().execute();
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction transaction) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction transaction) {
if(tab.getTag().equals("op")){
mPager.invalidate();
mPager.setAdapter(mOdapter);
mIndicator = (UnderlinePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}else if (tab.getTag().equals("dd")){
mPager.invalidate();
mPager.setAdapter(mDdapter);
mIndicator = (UnderlinePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}else if(tab.getTag().equals("ft")){
mPager.invalidate();
mPager.setAdapter(mFdapter);
mIndicator = (UnderlinePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction transaction) {
}
public static class AdapterOpiniao extends FragmentPagerAdapter {
public AdapterOpiniao(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return countopiniao;
}
#Override
public Fragment getItem(int position) {
return FragmentOpinioes.newInstance(position);
}
}
public static class AdapterDados extends FragmentPagerAdapter {
public AdapterDados(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return countdados;
}
#Override
public Fragment getItem(int position) {
return FragmentDados.newInstance(position);
}
}
public static class AdapterFoto extends FragmentPagerAdapter {
public AdapterFoto(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return countfoto;
}
#Override
public Fragment getItem(int position) {
return FragmentFotos.newInstance(position);
}
}
To solve your case, I used:
#Override
public void onTabSelected(Tab tab, FragmentTransaction transaction) {
this.mPager.setCurrentItem(tab.getPosition());
}
When a click on a tab, the view of the corresponding tab is automatically changed.
Edit: I must admit that I have some difficulties to really understand your code and what you are trying to do, so I add some more code to explain what i think you need.
In my optinion, only one adapter is necessary for the ViewPager, and then if I'm right, you would do so:
// I took some personal code for my example
private ViewPager mPager;
private PageIndicator mIndicator;
private TabsExampleSectionsAdapter mAdapter;
// Inside the onCreate method
this.mPager = (ViewPager) findViewById(R.id.pager);
this.mIndicator = new TabPageIndicator(this);
this.mAdapter = new TabsExampleSectionsAdapter(this.getSupportFragmentManager());
this.mPager.setAdapter(this.mAdapter);
this.mIndicator.setViewPager(this.mPager);
When everything is initialized, this is how to build tabs and pager views instructions (the two are related). Also, don't mind the Section class, it's a custom data model object which contains the tag data you need but it has nothing to do with actionbarsherlock.
private void buildTabs(Section[] sections) {
if (sections != null) {
for (Section section : sections) {
ActionBar.Tab sectionTab = getSupportActionBar().newTab();
sectionTab.setText(section.name);
sectionTab.setTabListener(this);
getSupportActionBar().addTab(sectionTab);
// The tag ("op" or "dd" in your case for example) is contained somewhere in the section object
this.mAdapter.getSections().add(section);
}
}
}
And finally, this is the view pager adapter. It will choose what type of fragment to return following the tags you defined for each tab position:
public class TabsExampleSectionsAdapter extends FragmentPagerAdapter {
private ArrayList<Section> mSectionsList = new ArrayList<Section>();
public TabsExampleSectionsAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
// Retrieving the cooresponding tag of position
Section section = this.mSectionsList.get(position % getCount());
// Here, you check the tag to know what type of fragment you must return
if (section.getTag().equals("dd")) {
return FragmentDados.newInstance(position);
} else if (section.getTag.equals("op")) {
return FragmentOp.newInstance(position);
}
}
#Override
public int getCount() {
return this.mSectionsList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return this.mSectionsList.get(position % getCount()).name.toUpperCase();
}
public ArrayList<Section> getSections() {
return this.mSectionsList;
}
}
In conclusion, when everything is set up, changing views doesn't have to be done manually by changing adapters and calling invalidate(). You can return different type of fragments from your adapter with a simple condition. Then, by calling:
this.mPager.setCurrentItem(position);
it changes automatically the current view by passing in the adapter's getItem(position) method. Basically, you just have to coordinate your tab positions and your tags in order to get the right type of fragment.
Feel free to ask for more details.

Categories

Resources