3

中的onBackPressed()方法,addToBackStack()方法无法正常工作下面是我编写的MainActivity代码。 我正在加载第一个屏幕中的片段列表。当用户点击任何列表项时,行星名称将在我已经在单独的类中定义的详细片段中向用户显示。如果不覆盖android

我将“Fragment Planet List” - >“Fragment Planet Detail”的事务添加回栈中。所以我期望的是,当我按下行星细节片段的后退按钮时,它应该在手机中加载行星列表。但这并不是这样发生的。

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

感谢。请让我知道是否需要任何额外的细节或代码。

+0

您定位的是哪个版本的android? –

+0

我针对运行ICS及以上版本的设备。 –

+0

同样的状况,相同的问题。还没有解决方案! :( 请让我知道,如果你发现任何东西 – mt0s

回答

6

好的。所以它不工作的原因是ActionBarActivty和Activity类差异的冲突。 和getSupportFragmentManager()之间的差异getFragmentManager()方法FragmentTransaction

ActionBarActivity:

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

片段管理器: 片段管理器不是从compat库。这是直接

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

,你可以在MainActivity类中看到。

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

所以,一旦我从ActionBarActivity更改为活动类,事情工作正常。 当我将FragmentManager,FragmentTransaction和Fragment类更改为支持库类时,情况同样如此。

所以经过任何修改后,事情开始正常工作。 谢谢。

+1

这解决了我的问题。答案是正确的。 – Behnam

0

当然,您不需要重写onBackPressed()方法。这只是一个黑客。

你的这种情况已经搞乱了。

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

为什么不使用这个语句没有条件一次,看看它是否工作。你可以保持原样。只要在if条件之外移动此声明即可。

+0

谢谢对于答案,我针对的是ICS及以上版本的设备,并且从if条件中删除它并不起作用 –

+0

我不认为Android版本与它有任何关系,您是否尝试将陈述放在if语句之外? 。 – Rohit5k2

+0

呀 FragmentPlanetDetail fragmentPlanetDetail = FragmentPlanetDetail.newInstance(strPlanetName); fragmentTransaction.addToBackStack(空); 如果(isPhone){ fragmentTransaction.replace(R.id.frmPlanetList,fragmentPlanetDetail) ; } else { fragmentTransaction.replace(R.id.frmPlanetDetail,fragmentPlanetDetail); } fragmentTransaction.commit(); –

0

奇怪,但我认为

addToBackStack(null) 

是问题

尝试用

addToBackStack("planetDetail"); 
+0

没有。它不起作用。 –

+0

尝试使用addToBackStack替换后? –

+0

在我的应用程序我只有1活动和6-7 fragmetns和一切都工作得很好,没有重写onBackPressed .... –

0

您正在使用的延伸片段活动动作条活动replcing它。现在,要有完美的行为,您需要支持片段才能使用操作栏活动。

在这里,您正在使用正常片段(不支持v4片段)的操作栏活动,这就是导致问题的原因。所以要有完美的行为,改变你的碎片支持碎片,它应该工作得很好。

让我知道这是行不通的。

0

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

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

import android.support.v4.app.Fragment; 

  • getFragmentManager()与getSupportFragmentManager():