Reputation: 104
I used the google developers example in order to make a slider of Views screen-slide
Everything was working fine, at the moment I implemented the onclick listener to change to the next fragment, the activity was working fine, at the moment I hit the back btn or go back and press another answer, the app shows:
FragmentManager is already executing transactions
It shows that the process is being called from pager.java and fragment2.java
Here are the samples:
ThaTransfomer.java
package name of the package
import android.support.v4.view.ViewPager;
import android.view.View;
public class ThaTransformer implements ViewPager.PageTransformer{
private static final float MIN_SCALE =0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position){
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if(position < -1){
view.setAlpha(0);
}else if(position <=1){
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
float ThaResult0 = horzMargin - vertMargin / 2;
float ThaResultNon0 = horzMargin + vertMargin / 2;
if(position < 0){
view.setTranslationX(ThaResult0);
}else{
view.setTranslationX(ThaResultNon0);
}
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
}else{
view.setAlpha(0);
}
}
}
Pager.java
public class Pager extends FragmentActivity {
/*Number of Pages*/
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);
Button prevBtn = (Button) findViewById(R.id.previous);
Button nextBtn = (Button) findViewById(R.id.next);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setPageTransformer(true, new ThaTransformer());
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
prevBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
prevItem();
}
});
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nextItem();
}
});
}
@Override
public void onBackPressed(){
if(mPager.getCurrentItem()==0){
/*Prevent bug if user is on first step*/
super.onBackPressed();
}else{
/*Previous item*/
mPager.setCurrentItem(mPager.getCurrentItem()-1);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter{
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch(position)
{
case 0: return new SurveyFragment1();
case 1: return new SurveyFragment2();
case 2: return new SurveyFragment3();
case 3: return new SurveyFragment4();
case 4: return new SurveyFragment5();
default : return new SurveyFragment1();
}
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
public boolean nextItem(){
int nextItemVar = mPager.getCurrentItem();
if(nextItemVar<=3){
Log.d("Next XD", ""+mPager.getCurrentItem());
}else{
Log.d("Yay! XD", ""+mPager.getCurrentItem());
new SweetAlertDialog(this, SweetAlertDialog.SUCCESS_TYPE)
.setTitleText("Encuesta enviada")
.setContentText("¡Gracias por llenar la encuesta!")
.show();
}
mPager.setCurrentItem(nextItemVar + 1);
return true;
}
public boolean prevItem(){
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
return true;
}
}
Survey Fragment 1
public class SurveyFragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_slide_page1, container, false);
RadioGroup radioGroup = (RadioGroup) rootView.findViewById(R.id.ans_group1);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
//nextItem();
((Pager) getActivity()).nextItem();
/**/
}
});
return rootView;
}
}
Survey Fragment 2
public class SurveyFragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_slide_page2, container, false);
RadioGroup radioGroup = (RadioGroup) rootView.findViewById(R.id.ans_group2);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
//nextItem();
((Pager) getActivity()).nextItem();
}
});
return rootView;
}
}
Survey Fragment 3
public class SurveyFragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_screen_slide_page3, container, false);
RadioGroup radioGroup = (RadioGroup) rootView.findViewById(R.id.ans_group3);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.pager);
public void onCheckedChanged(RadioGroup group, int checkedId) {
//nextItem();
((Pager) getActivity()).nextItem();
}
});
return rootView;
}
}
And the list goes on and on, as I said before, answering the first time it shows the desired effect, if you swipe back it goes back, the errors are shown when:
Upvotes: 2
Views: 9123
Reputation: 104
I finally find a work arround, with the help of Tobliug I was able to see that my function nextItem was being triggered at the same time the back transaction was happening, hence the error of the transactions.
In order to work arround this error I create a public void function inside the main activity and place this in the XML file using the following:
android:onClick="FN"
Thank you very much for your assistance Tobliug!
Upvotes: 0
Reputation: 3042
I finally found a fix/hack in my case.
I think the issue is that when you reCreate your fragment, OnCreateView is called with a non null savedInstanceState. It means that the previous instance of your fragment was saved somewhere. Because of this saved instance, something happens deeper in the code and make the ((Pager) getActivity()).nextItem() call automatically during the fragment creation:
Here is my Hack - just reset your radio button and move your change listener right after the state is restored :
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
//hack to prevent the view to display previous selection
radioGroup .clearCheck();
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.pager);
public void onCheckedChanged(RadioGroup group, int checkedId) {
//nextItem();
((Pager) getActivity()).nextItem();
}
});
}
Hope it will help !
Upvotes: 2