片段硬件后退按钮事件调用两次

时间:2017-03-15 08:36:30

标签: android android-fragments

我正在尝试通过我的片段实现反向导航,这些片段按特定顺序调用:A - > B - > C然后返回硬件按钮我会喜欢他们保持秩序。

我正在使用fragmenttransaction.replace来切换没有addToBackStack的片段,因为它使ActionBarMenu行为不端。

问题是,当我处于片段C时,后退按钮会直接返回A。我发现这是因为click事件被执行了两次我将B并直接转到A

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    setOnBackButtonPresed();
}

private void setOnBackButtonPresed() {
    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener( new View.OnKeyListener()
    {
        @Override
        public boolean onKey( View v, int keyCode, KeyEvent event )
        {
            if( keyCode == KeyEvent.KEYCODE_BACK )
            {
                goBackToDays();
                return false;
            }
            return false;
        }
    } );
}

private void goBackToDays() {
    Log.e("fragmentC", "executing on back action")
}

logcat结果:

03-15 08:37:17.353 21245-21245/com.test E/fragmentC: executing on back action
03-15 08:37:17.390 21245-21245/com.test E/fragmentC: executing on back action

任何人都可以提示我如何避免两次按钮事件吗?

5 个答案:

答案 0 :(得分:2)

我认为"点击事件执行两次"因为你同时调用ACTION_DOWN和ACTION_UP事件。试试这个

@Override
    public boolean onKey( View v, int keyCode, KeyEvent event )
    {
        if( keyCode == KeyEvent.KEYCODE_BACK && event.getAction()== KeyEvent.ACTION_DOWN)
        {
            goBackToDays();
            return false;
        }
        return false;
    }

答案 1 :(得分:1)

你可以做两件事

  1. "它让我的ActionBarMenu行为不端。"修复此问题。
  2. 覆盖您的Activity上的onBackPressed(),找到您当前加载的片段,并替换为您想要的任何一个。

    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.your_view_container);
    if (fragment instanceof FragmentThree) {
          //replace with your fragment ie. FragmentTwo
    } else if (fragment instanceof FragmentTwo) {
          //replace with your fragment ie. FragmentOne
    }
    

答案 2 :(得分:1)

2件事:

  1. 即使你是replacing个片段,旧的OnKeyListener也会留在那里(之后会被点燃)。尝试删除切换片段上的旧OnKeyListener
  2. 正如S-lightning指出的那样,您需要记住,有两项与关键事件相关的操作(KeyEvent.ACTION_DOWNKeyEvent.ACTION_UP)。

答案 3 :(得分:0)

如果您想要吸收"那么请返回true。关键事件并阻止它传播到Activity,它有自己的onBackPressed()实现。

if( keyCode == KeyEvent.KEYCODE_BACK )
{
    goBackToDays();
    return true; // <-- should be TRUE, not FALSE
}
return false;

答案 4 :(得分:0)

覆盖托管活动中的onBackPressed()方法。 这样做。

private void replaceFragment (Fragment fragment){
  String backStateName = fragment.getClass().getName();

  FragmentManager manager = getSupportFragmentManager();
  boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);

  if (!fragmentPopped){ //fragment not in back stack, create it.
     FragmentTransaction ft = manager.beginTransaction();
     ft.replace(R.id.content_frame, fragment);
     ft.addToBackStack(backStateName);
     ft.commit();
  }
}
.

.

@Override
public void onBackPressed(){
  if (getSupportFragmentManager().getBackStackEntryCount() == 1){
    finish();
  }
  else {
    super.onBackPressed();
  }
}

这是解释得很好的答案。 link