我的活动中有一些碎片

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

如果当前活动片段是[2],那么在返回按钮上按下我必须从[2]返回到[1],否则什么也不做。

最好的做法是什么?

编辑:应用程序不能从[3]…[6]返回[2]


当前回答

这是一个非常好的和可靠的解决方案: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;
    }
}

其他回答

当你在Fragments之间转换时,调用addToBackStack()作为FragmentTransaction的一部分:

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

如果你需要更详细的控制(例如,当一些片段可见时,你想要抑制返回键),你可以在你的片段的父视图上设置一个OnKeyListener:

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

我宁愿这样做:

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

创建接口:

后退按钮处理程序接口

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

OnBackClickListener

public interface OnBackClickListener {
     boolean onBackClick();
}

在活动:

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

在片段:

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

}

更新

提供自定义向后导航

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }

}

工作代码:

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