【问题标题】:Android backstack functioning for fragments用于片段的 Android 后台堆栈功能
【发布时间】:2016-01-07 05:13:00
【问题描述】:

我编写了一个代码,尝试在片段 1、2、3、4 之间导航。导航类似于:1->2->3->4->2.

每个片段都有一个按钮,其onClickListener调用mainactivity实现的接口中的方法,其中位置作为参数传递。

例如onClick 在第 4 个片段中的按钮调用方法,其中我将位置参数传递为 '2' 以调用第二个片段。

现在,我已将事务 1->2 添加到后台堆栈,使用后台堆栈名称“second”。当我尝试从 4>2 开始时,我使用函数 popBackStackImmediate("second", 0)。但是,布尔响应为 false,堆栈中没有弹出任何内容。

我的问题是:

  1. 为什么 popBackStackImmediate 返回 false?
  2. 同一个函数中的第二个参数即flag有什么用?
  3. 当我们在后台添加事务时,事务被保存而不是片段。那么,当后台堆栈保存事务时,片段对象实际保存在哪里?

我的代码中的 MainActivity 是:

`

    public class MainActivity extends AppCompatActivity implements Frag1.OnFragmentInteractionListener, Frag2.OnFragmentInteractionListener, Frag3.OnFragmentInteractionListener, Frag4.OnFragmentInteractionListener {

LinearLayout layout;
Frag1 frag1;
Frag2 frag2;
Frag3 frag3;
Frag4 frag4;
android.support.v4.app.FragmentTransaction transaction;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i("I", "Main Act");
    layout = (LinearLayout) findViewById(R.id.frag);
    frag1 = Frag1.newInstance();

    transaction = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.add(R.id.frag, frag1, "first");
  //  frag1 = Frag1.newInstance();
   // transaction.add(R.id.frag, frag1, "first1");
  //  transaction.add(R.id.frag, frag2, "second");
   // transaction.add(R.id.frag, frag2, "second");
 //  transaction.add(R.id.frag, frag3, "third");
    // Commit the transaction
  //  transaction.add(R.id.frag, frag3, "third");

  //  transaction.replace(R.id.frag, frag2, "second");

    transaction.commit();



}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

// Fragment到Activity接口实现

@Override
public void onFragmentInteraction(int pos) {

    if (pos == 2) {
       // Fragment f = getSupportFragmentManager().findFragmentByTag("second");
        FragmentManager manager = getSupportFragmentManager();

        boolean isAvail =  manager.popBackStackImmediate("second", 0);

        if (isAvail) {
           // frag2 = (Frag2) f;
            Log.i("MainAct", "Instance of 2 yes");
        }else{
            transaction = getSupportFragmentManager().beginTransaction();
           frag2 = Frag2.newInstance();
            Log.i("MainAct", "Instance of 2 No");
            transaction.replace(R.id.frag, frag2, "second");
            transaction.addToBackStack("second");
            transaction.commit();
        }



    } else if (pos == 3) {
        Fragment f = getSupportFragmentManager().findFragmentByTag("third");
        transaction = getSupportFragmentManager().beginTransaction();
        if (f instanceof Frag3) {
            frag3 = (Frag3) f;
            Log.i("MainAct", "Instance of 3 yes");
        }else{
            frag3 = Frag3.newInstance();
            Log.i("MainAct", "Instance of 3 No");
        }
        transaction.replace(R.id.frag, frag3, "third");

        transaction.commit();
        }

    else if (pos == 4) {
        Fragment f = getSupportFragmentManager().findFragmentByTag("four");
        transaction = getSupportFragmentManager().beginTransaction();
        if (f instanceof Frag3) {
            frag4 = (Frag4) f;
            Log.i("MainAct", "Instance of 4 yes");
        }else{
            frag4 = Frag4.newInstance();
            Log.i("MainAct", "Instance of 4 No");
        }
        transaction.replace(R.id.frag, frag4, "four");
        transaction.commit();
    }

    }

}`

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    您正在尝试调用 popBackStackImmediate("second", 0); 来替换片段。

    试试这个,

    1. 创建接口PageTraveller并在MainActivity中实现

      public interface PageTraveller {
          public void openPage(int pageNo);
      }
      
    2. 覆盖方法 openPage()

           @Override
          public void openPage(int pageNo) {
              android.support.v4.app.Fragment fragment;
              switch (pageNo){
                  case 1:
                      fragment = getSupportFragmentManager().findFragmentByTag("fragmentOne");
                      fragmentManager.beginTransaction().replace(R.id.pageContainer,fragment).addToBackStack("fragmentOne").commit();
                      break;
                  case 2:
                      fragment = getSupportFragmentManager().findFragmentByTag("fragmentTwo");
                      if (fragment instanceof FragmentTwo)
                          fragmentTwo = (FragmentTwo)fragment;
                      else
                          fragmentTwo = new FragmentTwo();
                      fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentTwo).addToBackStack("fragmentTwo").commit();
                      break;
                  case 3:
                      fragment = getSupportFragmentManager().findFragmentByTag("fragmentThree");
                      if (fragment instanceof FragmentTwo)
                          fragmentThree = (FragmentThree)fragment;
                      else
                          fragmentThree = new FragmentThree();
                      fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentThree).addToBackStack("fragmentThree").commit();
                      break;
                  case 4:
                      fragment = getSupportFragmentManager().findFragmentByTag("fragmentFour");
                      if (fragment instanceof FragmentTwo)
                          fragmentFour = (FragmentFour)fragment;
                      else
                          fragmentFour = new FragmentFour();
                      fragmentManager.beginTransaction().replace(R.id.pageContainer,fragmentFour).addToBackStack("fragmentFour").commit();
                      break;
              }
          }
      
      1. 创建第一个片段 FragmentOne

        public class FragmentOne extends Fragment{ PageTraveller pageTraveller; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View viewOne = inflater.inflate(R.layout.fragment_one,null); Button btnOne = (Button)viewOne.findViewById(R.id.text1); btnOne.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pageTraveller.openPage(2); } }); return viewOne; } @Override public void onAttach(Context context) { super.onAttach(context); pageTraveller = (PageTraveller) context; } }

      在 XML 片段中添加一个

      <Button
          android:id="@+id/btnOne"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:textSize="40dp"
          android:layout_gravity="center|center_horizontal|center_vertical"
          android:text="Fragment 1"/>
      

      1. 创建 FragmentTwo、FragmentThree、FragmentFour 的方法同上。 但在你的FragmentFour 打电话给pageTraveller.openPage(2);

    如需更多参考,请尝试 1.go back to the previous fragment in the backstack

    1. Fragments official Android Developer website

    它对我有用,试试它可能对你有帮助。

    【讨论】:

    • 您对替换片段的回答是正确的,但我怀疑是否重新定义了 pop 方法。它有什么用..我写的三个问题。
    • popBackStackImmediate(String name, int flags) 将弹出所有返回堆栈状态,直到具有给定标识符的状态。如果您真的想使用自己的代码来弹出片段,请使用getFragmentManager().popBackStack() 。更多参考请参考 1.stackoverflow.com/questions/10863572/…
    猜你喜欢
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多