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():