A、B、およびCの3つのタブがあるタブ付きActionbar/viewpagerレイアウトがあります。タブC tab(fragment)で、別のフラグメント、たとえばfragment Dを追加しています。と
DFragment f= new DFragment();
ft.add(Android.R.id.content, f, "");
ft.remove(CFragment.this);
ft.addToBackStack(null);
ft.commit();
ボタンを追加するには、DFragmentのonResumeでアクションバーを変更します。
ActionBar ab = getActivity().getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);
DFragmentで、ハードウェア(電話)の[戻る]ボタンを押すと、CFragmentが選択された元のTabbed(ABC)レイアウトに戻ります。アクションバーアップボタンでこの機能を実現するにはどうすればよいですか?
OnBackStackChangedListener
を実装し、このコードをフラグメントアクティビティに追加します。
@Override
public void onCreate(Bundle savedInstanceState) {
//Listen for changes in the back stack
getSupportFragmentManager().addOnBackStackChangedListener(this);
//Handle when activity is recreated like on orientation Change
shouldDisplayHomeUp();
}
@Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
boolean canGoBack = getSupportFragmentManager().getBackStackEntryCount()>0;
getSupportActionBar().setDisplayHomeAsUpEnabled(canGoBack);
}
@Override
public boolean onSupportNavigateUp() {
//This method is called when the up button is pressed. Just the pop back stack.
getSupportFragmentManager().popBackStack();
return true;
}
わかった。ホスティングアクティビティでonOptionsItemSelectedをオーバーライドし、バックスタックをポップアップします。
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
return true;
default:
return super.onOptionsItemSelected(item);;
}
}
以下の回答で説明されているように、getActionBar().setDisplayHomeAsUpEnabled(boolean);
でgetActionBar().setHomeButtonEnabled(boolean);
およびonBackStackChanged()
を呼び出します。
親アクティビティが1つあり、この上ボタンを戻るボタンとして機能させる場合は、次のコードを使用できます。
これをメインアクティビティクラスのonCreateに追加します
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment)
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}
}
});
次のようにonOptionsItemSelectedを追加します。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
....
}
私は通常これを常に使用し、かなり合法的なようです
戻るボタンのような上ボタンで戻ることができます。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
私はこの質問が古いことを知っていますが、(私のような)誰かがそれを必要とするかもしれません。
アクティビティがAppCompatActivityを拡張する場合、より単純な(2段階の)ソリューションを使用できます。
1-フラグメントトランザクションをコミットした直後に、ホーム以外のフラグメントを追加するたびに、[上へ]ボタンを表示します。このような:
// ... add a fragment
// Commit the transaction
transaction.commit();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
2-次に、UPボタンを押すと非表示になります。
@Override
public boolean onSupportNavigateUp() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
return true;
}
それでおしまい。
Roger Garzon Nieto's と sohailaziz's の回答を組み合わせて使用しました。私のアプリには単一のMainActivityがあり、それにロードされるフラグメントA、B、Cがあります。私の「ホーム」フラグメント(A)はOnBackStackChangedListenerを実装し、backStackのサイズをチェックします。 1未満の場合は、UPボタンが非表示になります。フラグメントBとCは常に戻るボタンをロードします(私の設計では、BはAから起動され、CはBから起動されます)。 MainActivity自体は、UPボタンタップでバックスタックをポップするだけで、フラグメントが呼び出すボタンを表示/非表示にするメソッドがあります。
MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case Android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
public void showUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); }
public void hideUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); }
fragmentA(FragmentManager.OnBackStackChangedListenerを実装):
public void onCreate(Bundle savedinstanceSate) {
// listen to backstack changes
getActivity().getSupportFragmentManager().addOnBackStackChangedListener(this);
// other fragment init stuff
...
}
public void onBackStackChanged() {
// enable Up button only if there are entries on the backstack
if(getActivity().getSupportFragmentManager().getBackStackEntryCount() < 1) {
((MainActivity)getActivity()).hideUpButton();
}
}
fragmentB、fragmentC:
public void onCreate(Bundle savedinstanceSate) {
// show the UP button
((MainActivity)getActivity()).showUpButton();
// other fragment init stuff
...
}
コトリン:
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
supportFragmentManager.addOnBackStackChangedListener { setupHomeAsUp() }
setupHomeAsUp()
}
private fun setupHomeAsUp() {
val shouldShow = 0 < supportFragmentManager.backStackEntryCount
supportActionBar?.setDisplayHomeAsUpEnabled(shouldShow)
}
override fun onSupportNavigateUp(): Boolean =
supportFragmentManager.popBackStack().run { true }
...
}
これは私のために働いた。たとえば、onSupportNavigateUpおよびonBackPressedをオーバーライドします(Kotlinのコード)。
override fun onBackPressed() {
val count = supportFragmentManager.backStackEntryCount
if (count == 0) {
super.onBackPressed()
} else {
supportFragmentManager.popBackStack()
}
}
override fun onSupportNavigateUp(): Boolean {
super.onSupportNavigateUp()
onBackPressed()
return true
}
フラグメント内で、上矢印を表示すると
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
クリックすると、前のアクティビティに戻ります。
これは非常に優れた信頼できるソリューションです。 http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/
男は、backPressの動作を処理する抽象フラグメントを作成し、戦略パターンを使用してアクティブフラグメントを切り替えています。
あなたの中には、抽象クラスに少し欠点があるかもしれません...
まもなく、リンクからのソリューションは次のようになります。
// Abstract Fragment handling the back presses
public abstract class BackHandledFragment extends Fragment {
protected BackHandlerInterface backHandlerInterface;
public abstract String getTagText();
public abstract boolean onBackPressed();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else {
backHandlerInterface = (BackHandlerInterface) getActivity();
}
}
@Override
public void onStart() {
super.onStart();
// Mark this fragment as the selected Fragment.
backHandlerInterface.setSelectedFragment(this);
}
public interface BackHandlerInterface {
public void setSelectedFragment(BackHandledFragment backHandledFragment);
}
}
アクティビティでの使用:
// BASIC ACTIVITY CODE THAT LETS ITS FRAGMENT UTILIZE onBackPress EVENTS
// IN AN ADAPTIVE AND ORGANIZED PATTERN USING BackHandledFragment
public class TheActivity extends FragmentActivity implements BackHandlerInterface {
private BackHandledFragment selectedFragment;
@Override
public void onBackPressed() {
if(selectedFragment == null || !selectedFragment.onBackPressed()) {
// Selected fragment did not consume the back press event.
super.onBackPressed();
}
}
@Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.selectedFragment = selectedFragment;
}
}