FragmentManager已经在执行Android事务

时间:2017-03-27 20:15:21

标签: android android-fragments

我使用谷歌开发者示例来制作视图滑块 屏幕幻灯片

一切都工作正常,此刻我实施了onclick监听器以更改为下一个片段,活动工作正常,此刻我点击后面btn或返回并按另一个答案,应用程序显示:< / p>

FragmentManager已经在执行交易

它显示正在从pager.java和fragment2.java

调用该进程

以下是样本:

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;
}

}

调查片段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;
}

}

调查片段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;
}

}

调查片段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;
}
}

正如我之前所说的那样,列表一直在继续,在第一次显示所需效果时回答,如果你向后滑动它会返回,错误会在以下时间显示:

  1. 点击后面的btn
  2. 对已经回答的问题给出不同的答案。

2 个答案:

答案 0 :(得分:2)

我终于在我的案例中发现了修复/黑客攻击。

我认为问题在于,当您重新创建片段时,使用非null savedInstanceState调用OnCreateView。这意味着您片段的前一个实例已保存在某处。 由于这个保存的实例,代码中更深层次的东西会在片段创建过程中自动调用((Pager)getActivity())。nextItem():

  1. 您的Fragment是create:调用OnCreateView,您可以在其中设置setOnCheckedChangeListener方法。
  2. savedInstanceState尝试使用以前的状态更新您的片段
  3. 您的不同RadioGroup将重新设置为之前的值,并触发setOnCheckedChangeListener。
  4. 你的((寻呼机)getActivity())。nextItem();调用方法并生成异常。
  5. 这是我的Hack - 只需重置单选按钮并在状态恢复后立即移动更改侦听器:

    @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();
    
           }
       });
    }
    

    希望它会有所帮助!

答案 1 :(得分:0)

我终于找到了一个工作,在Tobliug的帮助下,我能够看到我的函数nextItem在后台事务发生的同时被触发,因此交易错误。

为了解决此错误,我在main活动中创建了一个public void函数,并使用以下内容将其放在XML文件中:

android:onClick="FN"

非常感谢你对Tobliug的帮助!