I solved the problem.
I made an own history:
import java.util.ArrayList;
public class HistoryData {
static ArrayList<String> history = new ArrayList<>();
static ArrayList<String> historyForward = new ArrayList<>();
private static final String TAG = "HistoryData";
public static String lastItem = "";
public static int actItem = 0;
public static void add(String item){
if(history.size() == 0)
history.add(item);
if (!item.equals(history.get(history.size() - 1)) && !lastItem.equals(item)) {
history.add(item);
}
actItem = history.size() - 1;
Log.d(TAG, "add: " + item);
for (int i = 0; i < history.size(); i++){
Log.d(TAG, "get: index(" + i + ") = " + history.get(i));
}
}
public static int size(){
return history.size();
}
public static String get(int index){
Log.d(TAG, "get: " + history.get(index));
Log.d(TAG, "get: at index: " + index);
for (int i = 0; i < history.size(); i++){
Log.d(TAG, "get: index(" + i + ") = " + history.get(i));
}
return history.get(index);
}
public static String getLast(){
return history.get(history.size() - 1);
}
public static String getPrev(){
return history.get(history.size() - 2);
}
public static String remove(int index){
Log.d(TAG, "remove: " + history.get(index));
Log.d(TAG, "remove: at index: " + index);
historyForward.add(history.get(index));
actItem = history.size() - 1;
for (int i = 0; i < historyForward.size(); i++){
Log.d(TAG, "remove: hFw(" + i + ") = " + historyForward.get(i));
}
return history.remove(index);
}
public static int undoSize(){
return historyForward.size();
}
public static String undo(){
String result = historyForward.get(historyForward.size() - 1);
add(result);
historyForward.remove(historyForward.size() - 1);
for (int i = 0; i < historyForward.size(); i++){
Log.d(TAG, "undo: hFw(" + i + ") = " + historyForward.get(i));
}
return result;
}
}
I made a Navigate class
import android.util.Log;
import com.google.android.material.navigation.NavigationView;
import com.wecreatethefuture.puskapp.Activities.MainActivity;
import com.wecreatethefuture.puskapp.data.Constant;
import com.wecreatethefuture.puskapp.data.HistoryData;
public class Navigate {
private static final String TAG = "Navigate";
public static void back(){
MainActivity mainActivity = new MainActivity();
NavigationView navigationView = mainActivity.navPub();
Log.d(TAG, "handleOnBackPressed: HD size: " + HistoryData.size());
if (HistoryData.size() > 1){
String prev = HistoryData.getPrev();
Log.d(TAG, "handleOnBackPressed: prev: " + prev);
HistoryData.remove(HistoryData.size() - 1);
if(prev.equals(Constant.FRAGMENT_SETTING)){
navigationView.getMenu().performIdentifierAction(R.id.nav_settings, 0);
}
else if(prev.equals(Constant.FRAGMENT_LIBRARY)){
navigationView.getMenu().performIdentifierAction(R.id.nav_library, 0);
}
else if(prev.equals(Constant.FRAGMENT_GDPR)){
navigationView.getMenu().performIdentifierAction(R.id.nav_gdpr, 0);
}
else if(prev.equals(Constant.FRAGMENT_FAVORITES)){
navigationView.getMenu().performIdentifierAction(R.id.nav_favourites, 0);
}
else if(prev.equals(Constant.FRAGMENT_VIDEOS)){
navigationView.getMenu().performIdentifierAction(R.id.nav_video, 0);
}
else if(prev.equals(Constant.FRAGMENT_CATEGORIES)){
navigationView.getMenu().performIdentifierAction(R.id.nav_categories, 0);
}
else if(prev.equals(Constant.FRAGMENT_CHEATS)){
navigationView.getMenu().performIdentifierAction(R.id.nav_cheats, 0);
}
else if(prev.equals(Constant.FRAGMENT_ACT_CATEGORY_ITEM)){
navigationView.getMenu().performIdentifierAction(R.id.nav_act_category_item, 0);
} else
navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
} else {
navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
}
}
public static void forward(){
MainActivity mainActivity = new MainActivity();
NavigationView navigationView = mainActivity.navPub();
Log.d(TAG, "handleOnBackPressed: HD size: " + HistoryData.size());
if (HistoryData.undoSize() > 0){
String next = HistoryData.undo();
HistoryData.add(next);
if(next.equals(Constant.FRAGMENT_SETTING)){
navigationView.getMenu().performIdentifierAction(R.id.nav_settings, 0);
}
else if(next.equals(Constant.FRAGMENT_LIBRARY)){
navigationView.getMenu().performIdentifierAction(R.id.nav_library, 0);
}
else if(next.equals(Constant.FRAGMENT_GDPR)){
navigationView.getMenu().performIdentifierAction(R.id.nav_gdpr, 0);
}
else if(next.equals(Constant.FRAGMENT_FAVORITES)){
navigationView.getMenu().performIdentifierAction(R.id.nav_favourites, 0);
}
else if(next.equals(Constant.FRAGMENT_VIDEOS)){
navigationView.getMenu().performIdentifierAction(R.id.nav_video, 0);
}
else if(next.equals(Constant.FRAGMENT_CATEGORIES)){
navigationView.getMenu().performIdentifierAction(R.id.nav_categories, 0);
}
else if(next.equals(Constant.FRAGMENT_CHEATS)){
navigationView.getMenu().performIdentifierAction(R.id.nav_cheats, 0);
}
else if(next.equals(Constant.FRAGMENT_ACT_CATEGORY_ITEM)){
navigationView.getMenu().performIdentifierAction(R.id.nav_act_category_item, 0);
} else
navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
} else {
navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
}
}
}
I found an OnSwipeTouchListener after some Google search
import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class OnSwipeTouchListener implements View.OnTouchListener {
private GestureDetector gestureDetector;
Context c;
public OnSwipeTouchListener(Context c) {
gestureDetector = new GestureDetector(c, new GestureListener());
this.c = c;
}
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent);
}
private final class GestureListener extends
GestureDetector.SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return super.onDown(e);
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
onClick();
return super.onSingleTapUp(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
onDoubleClick();
return super.onDoubleTap(e);
}
@Override
public void onLongPress(MotionEvent e) {
onLongClick();
super.onLongPress(e);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
}
}
catch (Exception exception) {
exception.printStackTrace();
}
return false;
}
}
public void onSwipeRight() {
Navigate.back();
}
public void onSwipeLeft() {
Navigate.forward();
}
private void onClick() {
}
private void onDoubleClick() {
}
private void onLongClick() {
}
and finally I used them in Fragments with OnBackPressed events and onTouch listener (because I use swipe for back stack too)
This is the onCreate method in fragments:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HistoryData.add(Constant.FRAGMENT_ACT_CATEGORY_ITEM);
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
Navigate.back();
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
And I attached the OnSwieTouchListener to my view e.g.:
ConstraintLayout constraintLayout = root_view.findViewById(R.id.constraintLayoutCategoryItemContainer);
constraintLayout.setOnTouchListener(new OnSwipeTouchListener(getActivity().getBaseContext()) {
@Override
public void onSwipeLeft() {
super.onSwipeLeft();
}
@Override
public void onSwipeRight() {
super.onSwipeRight();
}
});