【问题标题】:addToBackStack() method is not working without overriding the onBackPressed() method in android如果不覆盖 android 中的 onBackPressed() 方法,addToBackStack() 方法将不起作用
【发布时间】:2015-02-23 21:05:02
【问题描述】:

这是我写的 MainActivity 的代码。 我正在第一个屏幕中加载片段列表。当用户点击任何列表项时,行星名称将在我在单独的类中定义的详细信息片段中显示给用户。

我正在将“碎片星球列表”->“碎片星球详细信息”的交易添加到后台堆栈。所以我期望的是当我从行星细节片段中按下后退按钮时,它应该在手机中加载行星列表。但事实并非如此。

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;

import com.meditab.fragments.fragment.FragmentPlanetDetail;
import com.meditab.fragments.fragment.FragmentPlanetList;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends ActionBarActivity implements Callback {

    private FrameLayout frmPlanetList;
    private FrameLayout frmPlanetDetail;
    private boolean isPhone;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        frmPlanetList = (FrameLayout) findViewById(R.id.frmPlanetList);
        frmPlanetDetail = (FrameLayout) findViewById(R.id.frmPlanetDetail);

        if (null != frmPlanetDetail) {
            isPhone = false;
        } else {
            isPhone = true;
        }

        FragmentManager fragmentManager = getFragmentManager();

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        fragmentTransaction.replace(R.id.frmPlanetList, new FragmentPlanetList());

        fragmentTransaction.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);
    }

    @Override
    public void onListItemClicked(int intPosition) {

        FragmentManager fragmentManager = getFragmentManager();

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        List<String> lstPlanetArray = getPlanetArray();
        String strPlanetName = lstPlanetArray.get(intPosition);

        FragmentPlanetDetail fragmentPlanetDetail = FragmentPlanetDetail.newInstance(strPlanetName);
        if (isPhone) {
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.replace(R.id.frmPlanetList, fragmentPlanetDetail);
        } else {
            fragmentTransaction.replace(R.id.frmPlanetDetail, fragmentPlanetDetail);
        }

        fragmentTransaction.commit();

    }

    private List<String> getPlanetArray() {
        List<String> lstPlanets = new ArrayList<>(10);
        lstPlanets.add("Mercury");
        lstPlanets.add("Venus");
        lstPlanets.add("Earth");
        lstPlanets.add("Mars");
        lstPlanets.add("Jupiter");
        lstPlanets.add("Saturn");
        lstPlanets.add("Uranus");
        lstPlanets.add("Neptune");
        lstPlanets.add("Saturn");

        return lstPlanets;
    }

}

但是,如果我重写 backPress 方法并以编程方式弹出返回堆栈,它就可以正常工作。

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() != 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

如果我想实现这种行为,是否需要以这种方式覆盖 onBackPressed() 方法? 未记录您需要在此链接中覆盖此方法。Android Back Press Fragment Documentation

片段星球细节类

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.meditab.fragments.R;

/**
 * Created by BHARGAV on 25-Dec-14.
 */
public class FragmentPlanetDetail extends Fragment {

    private String strPlanetName;

    public FragmentPlanetDetail() {

    }

    public static FragmentPlanetDetail newInstance(String strPlanetName) {
        FragmentPlanetDetail fragmentPlanetDetail = new FragmentPlanetDetail();

        Bundle bundle = new Bundle();
        bundle.putString("Planet_Name", strPlanetName);
        fragmentPlanetDetail.setArguments(bundle);
        return fragmentPlanetDetail;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle bundle = getArguments();
        if (null != bundle) {
            strPlanetName = bundle.getString("Planet_Name");
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.planet_name, container, false);

        TextView txtPlanetName = (TextView) rootView.findViewById(R.id.txtPlanetName);
        txtPlanetName.setText(strPlanetName);

        return rootView;
    }
}

碎片行星列表类:

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.meditab.fragments.Callback;
import com.meditab.fragments.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by BHARGAV on 25-Dec-14.
 */
public class FragmentPlanetList extends Fragment {

    private ListView listView;
    private ArrayAdapter<String> stringArrayAdapter;

    private Callback callback;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.listview, container, false);

        listView = (ListView) rootView.findViewById(R.id.listView);
        stringArrayAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_list_item_1, getPlanetArray());
        listView.setAdapter(stringArrayAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                callback.onListItemClicked(position);
            }
        });
        return rootView;
    }



    @Override
    public void onAttach(Activity activity) {

        super.onAttach(activity);

        callback = (Callback) activity;
    }

    private List<String> getPlanetArray() {
        List<String> lstPlanets = new ArrayList<>(5);
        lstPlanets.add("Mercury");
        lstPlanets.add("Venus");
        lstPlanets.add("Earth");
        lstPlanets.add("Mars");
        lstPlanets.add("Jupiter");
        lstPlanets.add("Saturn");
        lstPlanets.add("Uranus");
        lstPlanets.add("Neptune");
        lstPlanets.add("Saturn");

        return lstPlanets;
    }

}

回调接口:

/**
 * Created by BHARGAV on 26-Dec-14.
 */
public interface Callback {

    public void onListItemClicked(int intPosition);
}

谢谢。如果需要任何其他详细信息或代码,请告诉我。

【问题讨论】:

  • 你的目标是哪个版本的android?
  • 我的目标是运行 ICS 及以上的设备。
  • 同样的情况,同样的问题。还没有解决方案! :(如果你发现了什么请告诉我
  • 使用替换代码是问题所在。读一遍stackoverflow.com/questions/18634207/…

标签: android android-fragments fragmenttransaction onbackpressed


【解决方案1】:

当然你不需要重写onBackPressed() 方法。这只是一个 hack。

你的这种情况搞砸了。

if (isPhone) {
        fragmentTransaction.addToBackStack(null);

你为什么不使用这个无条件的语句一次看看它是否有效。你可以保持原样休息。只需将此语句移到 if 条件之外。

【讨论】:

  • 感谢您的回答。我的目标是 ICS 及以上设备。从 if 条件中删除它也不起作用。
  • 我认为安卓版本与此无关。您是否尝试将语句放在 if 语句之外?
  • 是的。 FragmentPlanetDetail fragmentPlanetDetail = FragmentPlanetDetail.newInstance(strPlanetName); fragmentTransaction.addToBackStack(null); if (isPhone) { fragmentTransaction.replace(R.id.frmPlanetList, fragmentPlanetDetail); } else { fragmentTransaction.replace(R.id.frmPlanetDetail, fragmentPlanetDetail); } fragmentTransaction.commit();
  • 不。它没。退出应用程序。
  • 这很奇怪,但现在覆盖后退按钮是解决方案。我从来不需要那样做。
【解决方案2】:

奇怪,但我认为

addToBackStack(null)

是问题

尝试替换它

addToBackStack("planetDetail");

【讨论】:

  • 在我的应用程序中,我只有 1 个活动和大约 6-7 个片段,并且在没有覆盖 onBackPressed 的情况下一切正常......
  • 是的,我在其他应用程序中也是如此。但它不适用于此应用程序。如果您可以尝试在您的 IDE 中实现它,那将非常有帮助
  • 我已经更新了整个代码。你能查一下吗?
  • 我会尝试,如果我找到解决方法会通知您
【解决方案3】:

您正在使用扩展片段活动的操作栏活动。现在,要拥有完美的行为,您需要支持片段来处理操作栏活动。

在这里,您正在使用带有普通片段(不支持 v4 片段)的操作栏活动,这就是导致问题的原因。因此,要拥有完美的行为,请更改您的片段以支持片段,它应该可以正常工作。

如果这不起作用,请告诉我。

【讨论】:

    【解决方案4】:

    嗯,我和你有同样的问题。什么对我有用,我认为它对你的解决方案也是改变:

    1.fragment 与支持库中的片段:

    import android.support.v4.app.Fragment;
    

    1. getFragmentManager() 与 getSupportFragmentManager() :

    【讨论】:

      【解决方案5】:

      好的。所以它不起作用的原因是ActionBarActivty和Activity类差异的冲突。 以及FragmentTransactiongetSupportFragmentManager()getFragmentManager()方法的区别。

      ActionBarActivity:

      我使用的是 android.support.v7.app.ActionBarActivity 的 ActionBarActivity。这意味着我使用的是 v7 兼容库

      片段管理器: 片段管理器不是来自兼容库。是直接

      import android.app.FragmentManager;
      import android.app.FragmentTransaction;
      

      正如您在 MainActivity 类中看到的那样。

      片段: android.app.Fragment;是在单独的片段类中导入的类。

      因此,一旦我从 ActionBarActivity 更改为 Activity 类,一切正常。 当我更改 FragmentManager、FragmentTransaction 和 Fragment 类以支持库类时也是如此。

      所以在进行任何修改后,一切都开始正常工作。 谢谢。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-21
        相关资源
        最近更新 更多