it-swarm.com.de

Android Zurück-Taste für Fragment-Griff drücken

Ich habe einige Fragmente in meiner Tätigkeit

[1], [2], [3], [4], [5], [6]

Drücken Sie die Taste "Zurück", um von [2] zu [1] zurückzukehren, wenn das derzeit aktive Fragment [2] ist, oder tun Sie nichts anderes.

Was ist die beste Vorgehensweise dafür?

EDIT: Die Anwendung darf nicht von [3] ... [6] zu [2] zurückkehren.

295
skayred

Wenn Sie zwischen Fragmenten wechseln, rufen Sie addToBackStack() als Teil Ihres FragmentTransaction auf:

FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag" ).commit();

Wenn Sie eine detailliertere Steuerung benötigen (d. H. Wenn einige Fragmente sichtbar sind, möchten Sie die Zurück-Taste unterdrücken), können Sie in der übergeordneten Ansicht Ihres Fragments ein OnKeyListener festlegen:

//You need to add the following line for this solution to work; thanks skayred
fragment.getView().setFocusableInTouchMode(true);
fragment.getView().requestFocus();
fragment.getView().setOnKeyListener( new OnKeyListener()
{
    @Override
    public boolean onKey( View v, int keyCode, KeyEvent event )
    {
        if( keyCode == KeyEvent.KEYCODE_BACK )
        {
            return true;
        }
        return false;
    }
} );
370
Mark Allison

Ich mache lieber so etwas:

private final static String TAG_FRAGMENT = "TAG_FRAGMENT";

private void showFragment() {
    final Myfragment fragment = new MyFragment();
    final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
    transaction.addToBackStack(null);
    transaction.commit();
}

@Override
public void onBackPressed() {
    final Myfragment fragment = (Myfragment) getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);

    if (fragment.allowBackPressed()) { // and then you define a method allowBackPressed with the logic to allow back pressed or not
        super.onBackPressed();
    }
}
259
saulobrito

wenn Sie die onKey-Methode für die Fragmentansicht überschreiben, benötigen Sie Folgendes:

    view.setFocusableInTouchMode(true);
    view.requestFocus();
    view.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                Log.i(tag, "keyCode: " + keyCode);
                if( keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                    Log.i(tag, "onKey Back listener is working!!!");
                    getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                    return true;
                } 
                return false;
            }
        });
105
ANemati

Verwenden addToBackStack Methode beim Ersetzen eines Fragments durch ein anderes:

getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).addToBackStack("my_fragment").commit();

Verwenden Sie dann in Ihrer Aktivität den folgenden Code, um von einem Fragment zu einem anderen (dem vorherigen) zurückzukehren.

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}
78
shimatai

Wenn Sie ein Hardware-Back-Key-Ereignis verarbeiten möchten, müssen Sie den folgenden Code in Ihrer onActivityCreated () - Methode von Fragment ausführen.

Sie müssen auch das Action_Down- oder Action_UP-Ereignis überprüfen. Wenn Sie dies nicht überprüfen, ruft die onKey () -Methode zweimal auf.

Wenn Ihre Root-Ansicht (getView ()) keinen Fokus enthält, funktioniert sie auch nicht. Wenn Sie auf ein Steuerelement geklickt haben, müssen Sie rootview erneut mit getView () den Fokus zuweisen. RequestFocus (); Danach ruft nur noch onKeydown () auf.

getView().setFocusableInTouchMode(true);
getView().requestFocus();

getView().setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        Toast.makeText(getActivity(), "Back Pressed", Toast.LENGTH_SHORT).show();
                    return true;
                    }
                }
                return false;
            }
        });

Ich arbeite sehr gut für mich.

43
Tejas Mehta

Der idealste Weg, dies zu tun, ist hier zu finden: Fragment: Welcher Rückruf wird aufgerufen, wenn die Rückruftaste gedrückt und angepasst wird

public class MyActivity extends Activity
{
    //...
    //Defined in Activity class, so override
    @Override
    public void onBackPressed()
    {
        super.onBackPressed();
        myFragment.onBackPressed();
    }
}

public class MyFragment extends Fragment
{
    //Your created method
    public static void onBackPressed()
    {
        //Pop Fragments off backstack and do your other checks
    }
}
25
kakoma

Schnittstellen erstellen:

BackButtonHandlerInterface

public interface BackButtonHandlerInterface {
    void addBackClickListener (OnBackClickListener onBackClickListener);
    void removeBackClickListener (OnBackClickListener onBackClickListener);
}

OnBackClickListener

public interface OnBackClickListener {
     boolean onBackClick();
}

In Aktivität:

public class MainActivity extends AppCompatActivity implements BackButtonHandlerInterface {

    private ArrayList<WeakReference<OnBackClickListener>> backClickListenersList = new ArrayList<>();

    @Override
    public void addBackClickListener(OnBackClickListener onBackClickListener) {
        backClickListenersList.add(new WeakReference<>(onBackClickListener));
    }

    @Override
    public void removeBackClickListener(OnBackClickListener onBackClickListener) {
        for (Iterator<WeakReference<OnBackClickListener>> iterator = backClickListenersList.iterator();
         iterator.hasNext();){
            WeakReference<OnBackClickListener> weakRef = iterator.next();
            if (weakRef.get() == onBackClickListener){
                iterator.remove();
            }
        }
    }

    @Override
    public void onBackPressed() {
        if(!fragmentsBackKeyIntercept()){
            super.onBackPressed();
        }
    }

    private boolean fragmentsBackKeyIntercept() {
        boolean isIntercept = false;
        for (WeakReference<OnBackClickListener> weakRef : backClickListenersList) {
            OnBackClickListener onBackClickListener = weakRef.get();
            if (onBackClickListener != null) {
                boolean isFragmIntercept = onBackClickListener.onBackClick();
                if (!isIntercept) isIntercept = isFragmIntercept;
            }
        }
        return isIntercept;
    }
}

In Fragment:

public class MyFragment extends Fragment implements OnBackClickListener{

    private BackButtonHandlerInterface backButtonHandler;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        backButtonHandler = (BackButtonHandlerInterface) activity;
        backButtonHandler.addBackClickListener(this);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        backButtonHandler.removeBackClickListener(this);
        backButtonHandler = null;
    }

    @Override
    public boolean onBackClick() {
        //This method handle onBackPressed()! return true or false
        return false;
    }

}
19
krawa
 @Override
    public void onResume() {

        super.onResume();

        getView().setFocusableInTouchMode(true);
        getView().requestFocus();
        getView().setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)){
                        mDrawerLayout.closeDrawer(GravityCompat.START);
                    }
                    return true;
                }

                return false;
            }
        });
    }
10

Wenn Sie den Ablauf des Hinzufügens jeder Transaktion zum Backstack verwalten, können Sie so etwas tun, um das vorherige Fragment anzuzeigen, wenn der Benutzer die Zurück-Taste drückt (Sie können auch die Home-Taste zuordnen).

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0)
        getFragmentManager().popBackStack();
    else
        super.onBackPressed();
}
5
Joaquin Iurchuk

Oder Sie können getSupportFragmentManager().getBackStackEntryCount() verwenden, um zu überprüfen, was zu tun ist:

@Override
    public void onBackPressed() {

        logger.d("@@@@@@ back stack entry count : " + getSupportFragmentManager().getBackStackEntryCount());

        if (getSupportFragmentManager().getBackStackEntryCount() != 0) {

            // only show dialog while there's back stack entry
            dialog.show(getSupportFragmentManager(), "ConfirmDialogFragment");

        } else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {

            // or just go back to main activity
            super.onBackPressed();
        }
    }
5
Robert

Wir haben eine winzige Bibliothek erstellt, um das Zurückdrücken über mehrere Fragmente und/oder in Activity hinweg zu handhaben. Die Verwendung ist so einfach wie das Hinzufügen von Abhängigkeiten in Ihrer gradle-Datei:

compile 'net.skoumal.fragmentback:fragment-back:0.1.0'

Lassen Sie Ihr Fragment die Schnittstelle BackFragment implementieren:

public abstract class MyFragment extends Fragment implements BackFragment {

    public boolean onBackPressed() {

        // -- your code --

        // return true if you want to consume back-pressed event
        return false;
    }

    public int getBackPriority() {
        return NORMAL_BACK_PRIORITY;
    }
}

Benachrichtigen Sie Ihre Fragmente über rückseitige Pressen:

public class MainActivity extends AppCompatActivity {

    @Override
    public void onBackPressed() {
        // first ask your fragments to handle back-pressed event
        if(!BackFragmentHelper.fireOnBackPressedEvent(this)) {
            // lets do the default back action if fragments don't consume it
            super.onBackPressed();
        }
    }
}

Weitere Details und andere Anwendungsfälle finden Sie auf der GitHub-Seite:

https://github.com/skoumalcz/fragment-back

5
gingo

Arbeitscode:

package com.example.keralapolice;

import Android.app.Fragment;
import Android.app.FragmentManager;
import Android.app.FragmentManager.OnBackStackChangedListener;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.Gravity;
import Android.view.KeyEvent;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.Toast;

public class ChiefFragment extends Fragment {
    View view;

    // public OnBackPressedListener onBackPressedListener;

    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle args) {

        view = inflater.inflate(R.layout.activity_chief, container, false);
        getActivity().getActionBar().hide();
        view.setFocusableInTouchMode(true);
        view.requestFocus();
        view.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                Log.i(getTag(), "keyCode: " + keyCode);
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    getActivity().getActionBar().show();
                    Log.i(getTag(), "onKey Back listener is working!!!");
                    getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                    // String cameback="CameBack";
                    Intent i = new Intent(getActivity(), home.class);
                    // i.putExtra("Comingback", cameback);
                    startActivity(i);
                    return true;
                } else {
                    return false;
                }
            }
        });
        return view;
    }
}
4
Android

Ich arbeite mit SlidingMenu und Fragment, präsentiere meinen Fall hier und hoffe, dass jemand hilft.

Logik beim Drücken der Taste [Zurück]:

  1. Wenn SlidingMenu angezeigt wird, schließen Sie es, es gibt keine weiteren Aktivitäten.
  2. Wenn das zweite (oder mehrere) Fragment angezeigt wird, können Sie zum vorherigen Fragment zurückkehren und haben keine weiteren Aufgaben mehr.
  3. SlidingMenu wird nicht angezeigt, aktuelles Fragment ist # 0, die ursprüngliche Taste [Zurück] wird ausgeführt.

    public class Main extends SherlockFragmentActivity
    {
      private SlidingMenu menu=null;
      Constants.VP=new ViewPager(this);
    
      //Some stuff...
    
      @Override
      public void onBackPressed()
      {
        if(menu.isMenuShowing())
        {
          menu.showContent(true); //Close SlidingMenu when menu showing
          return;
        }
        else
        {
          int page=Constants.VP.getCurrentItem();
          if(page>0)
          {
            Constants.VP.setCurrentItem(page-1, true); //Show previous fragment until Fragment#0
            return;
          }
          else
          {super.onBackPressed();} //If SlidingMenu is not showing and current Fragment is #0, do the original [Back] key does. In my case is exit from APP
        }
      }
    }
    
4
RRTW

Nachdem ich mir alle Lösungen angesehen hatte, stellte ich fest, dass es eine viel einfachere Lösung gibt.

Suchen Sie in Ihrer Aktivität onBackPressed (), in der alle Ihre Fragmente gehostet werden, das Fragment, das Sie verhindern möchten, dass Sie zurückdrücken. Wenn Sie gefunden werden, kehren Sie einfach zurück. Dann wird popBackStack für dieses Fragment niemals stattfinden.

  @Override
public void onBackPressed() {

        Fragment1 fragment1 = (Fragment1) getFragmentManager().findFragmentByTag(“Fragment1”);
        if (fragment1 != null)
            return;

        if (getFragmentManager().getBackStackEntryCount() > 0){
            getFragmentManager().popBackStack();

        }
}
3
Harry Aung

Dies ist eine sehr gute und zuverlässige Lösung: http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/

Der Typ hat ein abstraktes Fragment erstellt, das das Verhalten von backPress behandelt und mithilfe des Strategiemusters zwischen den aktiven Fragmenten wechselt.

Für einige von euch gibt es vielleicht ein kleines Manko in der abstrakten Klasse ...

In Kürze lautet die Lösung über den Link wie folgt:

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

Und Verwendung in der Aktivität:

// 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;
    }
}
3
Amio.io

Ich denke, der einfachste Weg ist, eine Schnittstelle zu erstellen und in der Aktivitätsprüfung zu prüfen, ob das Fragment vom Schnittstellentyp ist, und in diesem Fall seine Methode aufzurufen, um mit dem Popup umzugehen. Hier ist die Schnittstelle, die im Fragment implementiert werden soll.

public interface BackPressedFragment {

    // Note for this to work, name AND tag must be set anytime the fragment is added to back stack, e.g.
    // getActivity().getSupportFragmentManager().beginTransaction()
    //                .replace(R.id.fragment_container, MyFragment.newInstance(), "MY_FRAG_TAG")
    //                .addToBackStack("MY_FRAG_TAG")
    //                .commit();
    // This is really an override. Should call popBackStack itself.
    void onPopBackStack();
}

Hier erfahren Sie, wie Sie es implementieren.

public class MyFragment extends Fragment implements BackPressedFragment
    @Override
    public void onPopBackStack() {
        /* Your code goes here, do anything you want. */
        getActivity().getSupportFragmentManager().popBackStack();
}

Wenn Sie in Ihrer Aktivität mit dem Popup (wahrscheinlich sowohl in onBackPressed als auch in onOptionsItemSelected) umgehen, platzieren Sie den Backstack mit der folgenden Methode:

public void popBackStack() {
    FragmentManager fm = getSupportFragmentManager();
    // Call current fragment's onPopBackStack if it has one.
    String fragmentTag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName();
    Fragment currentFragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
    if (currentFragment instanceof BackPressedFragment)
        ((BackPressedFragment)currentFragment).onPopBackStack();
    else
        fm.popBackStack();
}
3
Matt Koala
            rootView.setFocusableInTouchMode(true);
            rootView.requestFocus();
            rootView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event)   {
            if (keyCode == KeyEvent.KEYCODE_BACK) {


                Fragment NameofFragment = new NameofFragment;

                FragmentTransaction  transaction=getFragmentManager().beginTransaction();
                transaction.replace(R.id.frame_container,NameofFragment);

                transaction.commit();

                return true;
            }
            return false;
        }
    });

    return rootView;
3
Ashish Soni

Sie können aus getActionBar().setDisplayHomeAsUpEnabled() Folgendes verwenden:

@Override
public void onBackStackChanged() {
    int backStackEntryCount = getFragmentManager().getBackStackEntryCount();

    if(backStackEntryCount > 0){
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }else{
        getActionBar().setDisplayHomeAsUpEnabled(false);
    }
}
2
user4501847

Für diejenigen, die statische Fragmente verwenden

In einem Fall, wenn Sie ein statisches Fragment haben, wäre es vorzuziehen. Machen Sie aus Ihrem Fragment ein Instanzobjekt

private static MyFragment instance=null;

initialisieren Sie diese Instanz in onCreate () von MyFragment

  instance=this;

machen Sie auch eine Funktion, um Instanz zu erhalten

 public static MyFragment getInstance(){
   return instance;
}

mache auch funktionen

public boolean allowBackPressed(){
    if(allowBack==true){
        return true;
    }
    return false;
}


 //allowBack is a boolean variable that will be set to true at the action 
 //where you want that your backButton should not close activity. In my case I open 
 //Navigation Drawer then I set it to true. so when I press backbutton my 
 //drawer should be get closed

public void performSomeAction(){
    //.. Your code
    ///Here I have closed my drawer
}

In Ihrer Aktivität können Sie tun

@Override
public void onBackPressed() {

    if (MyFragment.getInstance().allowBackPressed()) { 
        MyFragment.getInstance().performSomeAction();
    }
    else{
        super.onBackPressed();
    }
}
2
Muhammad Adil

wenn Sie FragmentActivity verwenden. dann mach das so

rufe dies zuerst in deinem Fragment auf.

public void callParentMethod(){
    getActivity().onBackPressed();
}

rufen Sie dann die Methode onBackPressed neben Ihrer übergeordneten Klasse FragmentActivity auf.

@Override
public void onBackPressed() {
  //super.onBackPressed();
  //create a dialog to ask yes no question whether or not the user wants to exit
  ...
}
1
hash

in der Fragment-Klasse setzen Sie diesen Code für das Back-Ereignis:

 rootView.setFocusableInTouchMode(true);
        rootView.requestFocus();
        rootView.setOnKeyListener( new OnKeyListener()
        {
            @Override
            public boolean onKey( View v, int keyCode, KeyEvent event )
            {
                if( keyCode == KeyEvent.KEYCODE_BACK )
                {
                    FragmentManager fragmentManager = getFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, new Book_service_provider()).commit();

                    return true;
                }
                return false;
            }
        } );
1
tej shah

Fügen Sie diesen Code in Ihre Aktivität ein

@Override

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

Fügen Sie diese Zeile in Ihr Fragment ein, bevor Sie commit () ausführen.

ft.addToBackStack ("Beliebiger Name");

1
Ravi

Fügen Sie addToBackStack () zur Fragmenttransaktion hinzu und verwenden Sie den folgenden Code zum Implementieren der Rückwärtsnavigation für Fragmente

getSupportFragmentManager().addOnBackStackChangedListener(
    new FragmentManager.OnBackStackChangedListener() {
        public void onBackStackChanged() {
            // Update your UI here.
        }
    });
1
Lalit Sharma

Die Überprüfung des Backstacks funktioniert einwandfrei


@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if (keyCode == KeyEvent.KEYCODE_BACK)
    {
        if (getFragmentManager().getBackStackEntryCount() == 1)
        {
            // DO something here since there is only one fragment left
            // Popping a dialog asking to quit the application
            return false;
        }
    }
    return super.onKeyDown(keyCode, event);
}
0
Devrath