1

ボトムナビゲーションバーで作業していますが、完全にボトムナビゲーションバーになっていません。 ボトムナビゲーションを完全にバックプレスで処理する方法

マイ MainActivityクラス:

public class MainActivity extends AppCompatActivity { 

    private static final String SELECTED_ITEM = "selected_item"; 

    private BottomNavigationView bottomNavigationView; 
    private Toolbar toolbar; 
    private MenuItem menuItemSelected; 
    private int mMenuItemSelected; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation); 
     bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
      @Override 
      public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
       selectFragment(item); 
       return true; 
      } 
     }); 

     //Always load first fragment as default 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.frameLayout, new AnnouncementFragment()); 
     fragmentTransaction.commit(); 

     if (savedInstanceState != null) { 
      mMenuItemSelected = savedInstanceState.getInt(SELECTED_ITEM, 0); 
      menuItemSelected = bottomNavigationView.getMenu().findItem(mMenuItemSelected); 
     } else { 
      menuItemSelected = bottomNavigationView.getMenu().getItem(0); 
     } 

     selectFragment(menuItemSelected); 
    } 

    private void selectFragment(MenuItem item) { 
     Fragment fragment = null; 
     Class fragmentClass; 
     switch (item.getItemId()) { 
      case R.id.action_announcement: 
       fragmentClass = AnnouncementFragment.class; 
       break; 
      case R.id.action_menu: 
       fragmentClass = MenuFragment.class; 
       break; 
      case R.id.action_menu_reports: 
       fragmentClass = ReportFragment.class; 
       break; 
      case R.id.action_setting: 
       fragmentClass = SettingFragment.class; 
       break; 

      default: 
       fragmentClass = AnnouncementFragment.class; 
     } 

     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction().replace(R.id.frameLayout, fragment).commit(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putInt(SELECTED_ITEM, mMenuItemSelected); 
     super.onSaveInstanceState(outState); 
    } 

そして、私の背中が正常に動作していないにも押された:

@Override 
    public void onBackPressed() { 
     MenuItem homeItem = bottomNavigationView.getMenu().getItem(0); 
     if (mMenuItemSelected != homeItem.getItemId()) { 
      selectFragment(homeItem); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

私がすべきどのようにその下のメニューバー上の不均一な分布を持っているので。どのように不均一な分布なしでメニュースペースを適切に維持するか。

ここで私は私がAVD First I

Another Selection

+0

正確には動作しません。あなたが得ようとしている行動や実際にあなたが得た予期しない行動を説明してください。 – Bryan

+0

BackPressedが正しく動作していません。設定アイコンを押したときに、アイコンの間に十分なスペースがあります。 –

+0

下部ナビゲーションバーのカスタマイズは必要ありません。 – Tony

答えて

3

私は同じ問題を昨日持ち、完璧に働いたアプローチを実装しました。他人を助けるために 、私はGitHubの上でいくつかの要旨を公表: 私はCustomBottomNavigationViewを作成しました: https://gist.github.com/shrpereira/201380de0a85630a93659549bc3a5f62

MainActivityでは、configureMenuNavigationメソッドへの注意: https://gist.github.com/shrpereira/7e8d698713614cd85081af59dbd880d2

例を完了するために、ここでBaseActivityのコードがありますこれはshowFragmentメソッドを提供します: https://gist.github.com/shrpereira/3fa0e94babb4c75db8d4ce16972ad85f

+0

非常に非常に感謝!! +1 –

0

使用addToBackStack方法このようなフラグメントを呼び出すときに、

getSupportFragmentManager().beginTransaction().addToBackStack(null).add(R.id.content_home_nav,newFragment).commit(); 

はあなたにこのコードを使用してくださいに取得した私の結果を添付していますonBackPressedメソッド

if (getSupportFragmentManager().getBackStackEntryCount() > 0){ 
     getFragmentManager().popBackStack(); 
    } else { 
     super.onBackPressed(); 
    } 
0

あなたの要件では、ナビゲーションのフラグメントを使って作業していますので、ビューページャーでTablayoutを使用してボトムナビゲーションを行うことができます。

<android.support.design.widget.TabLayout 
     android:id="@+id/tab_layout" 
     android:layout_width="match_parent" 
     android:layout_height="60dp"></android.support.design.widget.TabLayout> 

、その後、タブレイアウトとセットアップviewpagerと

tabLayout = (TabLayout) findViewById(R.id.tab_layout); 
    viewPager = (ViewPager) findViewById(R.id.controller_pager); 
    viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager())); 
    viewPager.setOffscreenPageLimit(4); 
    tabLayout.setupWithViewPager(viewPager); 
    tabLayout.getTabAt(0).setIcon(R.drawable.selector_home); 
    tabLayout.getTabAt(1).setIcon(R.drawable.selector_contact); 
    tabLayout.getTabAt(2).setIcon(R.drawable.selector_profile); 
    tabLayout.getTabAt(3).setIcon(R.drawable.selector_settings); 

は今tablayoutのクリックですべてのものを処理し、それがうまく tabLayout.addOnTabSelectedListener(これを)動作しますあなたの活動にtablayoutするアイコンを追加;

1

アンドロイドでMaterial Design

ためのガイドラインによると、戻るボタンが下 ナビゲーションバーのビュー間をナビゲートしていません。

つまり、戻るボタンをクリックすると、アプリケーションが終了します。これは、Googleフォトなどのデフォルトの動作です。

FragmentManager fragmentManager = getFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
fragmentTransaction.replace(R.id.content, fragment); 
// note: there is NOT a addToBackStack call 
fragmentTransaction.commit(); 

しかし、Googleではルールを作成して例外を使用しています。 Google+のようなもの ここで、戻るボタンは最初にホームセクションに進み、再び押した場合は終了します。

個人的には、この「Google+パターン」がはるかに優れています。

:あなたが持っている viewfragment方法を記述しているすべての他人あなたが今何をすべきか
navigation = (BottomNavigationView) findViewById(R.id.navigation); 
navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
    @Override 
    public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.navigation_home: 
       viewFragment(new HomeFragment(), FRAGMENT_HOME); 
       return true; 
      case R.id.navigation_page_1: 
       viewFragment(new OneFragment(), FRAGMENT_OTHER); 
       return true; 
      case R.id.navigation_page_2: 
       viewFragment(new TwoFragment(), FRAGMENT_OTHER); 
       return true; 
     } 
     return false; 
    } 
}); 

を自宅のフラグメントを識別し、 からそれを区別する必要がonBackPressed

は上書きせずにそれを得るために、

  1. commit
  2. 前にスタックにありますどのように多くの断片を知っています
  3. フラグメントは commit

  4. すなわち( 、スタックが低下したときにすることをOnBackStackChangedListenerを追加する前に、スタックに保存し、ない「ホームタイプ」である場合私が)戻って押されたときに、コメントをフル法の下には、家庭フラグメント

に私たちをもたらし、)(POP_BACK_STACK_INCLUSIVEない「ホームタイプ」であるすべての断片を削除

private void viewFragment(Fragment fragment, String name){ 
    final FragmentManager fragmentManager = getFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.replace(R.id.content, fragment); 
    // 1. Know how many fragments there are in the stack 
    final int count = fragmentManager.getBackStackEntryCount(); 
    // 2. If the fragment is **not** "home type", save it to the stack 
    if(name.equals(FRAGMENT_OTHER)) { 
     fragmentTransaction.addToBackStack(name); 
    } 
    // Commit ! 
    fragmentTransaction.commit(); 
    // 3. After the commit, if the fragment is not an "home type" the back stack is changed, triggering the 
    // OnBackStackChanged callback 
    fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      // If the stack decreases it means I clicked the back button 
      if(fragmentManager.getBackStackEntryCount() <= count){ 
       // pop all the fragment and remove the listener 
       fragmentManager.popBackStack(FRAGMENT_OTHER, POP_BACK_STACK_INCLUSIVE); 
       fragmentManager.removeOnBackStackChangedListener(this); 
       // set the home button selected 
       navigation.getMenu().getItem(0).setChecked(true); 
      } 
     } 
    }); 
} 
+0

は機能しません。 fragmentTransaction.addtoBackstack(name)が呼び出されたにもかかわらず、onBackStackChangedメソッドを呼び出すことはありません... –

0

私は同じ問題に直面していましたが、これを実行した後に解決策が得られました

最初にこのコードをメインアクティビティに貼り付けます(下部のナビゲーションバーを使用しています)

BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation); 
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView); 

そしてBottomNavigationViewHelperという名前のクラスを作成し、次のコードを貼り付けます。

public class BottomNavigationViewHelper { 
public static void disableShiftMode(BottomNavigationView view) { 
    BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); 
    try { 
     Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); 
     shiftingMode.setAccessible(true); 
     shiftingMode.setBoolean(menuView, false); 
     shiftingMode.setAccessible(false); 
     for (int i = 0; i < menuView.getChildCount(); i++) { 
      BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); 
      //noinspection RestrictedApi 
      item.setShiftingMode(false); 
      // set once again checked value, so view will be updated 
      //noinspection RestrictedApi 
      item.setChecked(item.getItemData().isChecked()); 
     } 
    } catch (NoSuchFieldException e) { 
     Log.e("BNVHelper", "Unable to get shift mode field", e); 
    } catch (IllegalAccessException e) { 
     Log.e("BNVHelper", "Unable to change value of shift mode", e); 
    } 
} 

}

それは

5

を役に立てば幸いこの

@Override 
    public void onBackPressed() { 
     BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation); 
     int seletedItemId = bottomNavigationView.getSelectedItemId(); 
     if (R.id.home != seletedItemId) { 
      setHomeItem(MainActivity.this); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

public static void setHomeItem(Activity activity) { 
    BottomNavigationView bottomNavigationView = (BottomNavigationView) 
      activity.findViewById(R.id.navigation); 
    bottomNavigationView.setSelectedItemId(R.id.home); 
} 
0

はこれを試してみてくださいしてみてください。

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 

      // Gets the previous global stack count 
      int previousStackCount = mPreviousStackCount; 

      // Gets a FragmentManager instance 
      FragmentManager localFragmentManager = getSupportFragmentManager(); 

      // Sets the current back stack count 
      int currentStackCount = localFragmentManager.getBackStackEntryCount(); 

      // Re-sets the global stack count to be the current count 
      mPreviousStackCount = currentStackCount; 

      boolean popping = currentStackCount < previousStackCount; 

      if(popping){ 
       bottomNavigationView.getMenu().getItem(0).setChecked(true); 
      } 

     } 
    }); 
0

この解決策を試してください。 問題のコードに変更を加えました。

私は、あなたのアプリがあなたのケースのアナウンスメントのフラグメントに戻ってくることを前提にしています。また、もう一度押すと、アプリケーションは終了します。

このフローは、下部ナビゲーションバーにも反映されます。

public class MainActivity extends AppCompatActivity { 
private static final String BACK_STACK_ROOT_TAG = "root_home_fragment"; 
private static final String SELECTED_ITEM = "selected_item"; 
private Fragment fragment; 
private FragmentManager fragmentManager; 
private BottomNavigationView bottomNavigationView; 
private Toolbar toolbar; 
private MenuItem menuItemSelected; 
private int mMenuItemSelected; 
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener 
     = new BottomNavigationView.OnNavigationItemSelectedListener() { 

    @Override 
    public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
     boolean selected = false; 
     switch (item.getItemId()) { 
      case R.id.action_announcement: 
       fragment = AnnouncementFragment.newInstance(); 
       selected = true; 
       break; 
      case R.id.action_menu: 
       fragment = MenuFragment.newInstance(); 
       selected = true; 
       break; 
      case R.id.action_menu_reports: 
       fragment = ReportFragment.newInstance(); 
       selected = true; 
       break; 
     case R.id.action_setting: 
     fragment = SettingFragment.newInstance(); 
       selected = true; 

     } 
     if(fragment !=null){ 
      fragmentManager = getFragmentManager(); 
      switch (item.getItemId()) { 
       case R.id.action_announcement: 
        // Pop every fragment from backstack including home fragment. 
        fragmentManager.popBackStack(BACK_STACK_ROOT_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
        fragmentManager.beginTransaction() 
          .replace(R.id.content, fragment) 
          .addToBackStack(BACK_STACK_ROOT_TAG) 
          .commit(); 
        break; 
       default: 

        fragmentManager.beginTransaction() 
          .replace(R.id.content, fragment) 
          .addToBackStack(null) 
          .commit(); 
        break; 
      } 
     } 
     return selected; 
    } 

}; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation); 
    bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); 

    //Always load first fragment as default 
    bottomNavigationView.setSelectedItemId(R.id.action_announcement); 

    if (savedInstanceState != null) { 
     mMenuItemSelected = savedInstanceState.getInt(SELECTED_ITEM, 0); 
     menuItemSelected = bottomNavigationView.getMenu().findItem(mMenuItemSelected); 
    } else { 
     menuItemSelected = bottomNavigationView.getMenu().getItem(0); 
    } 
} 



@Override 
protected void onSaveInstanceState(Bundle outState) { 
    outState.putInt(SELECTED_ITEM, mMenuItemSelected); 
    super.onSaveInstanceState(outState); 
} 

public void onBackPressed() { 
    int count = getFragmentManager().getBackStackEntryCount(); 
    if(count >1){ 
     // We have lots of fragment on backstack to be popped. 
     // Pop till the root fragment. 
     getFragmentManager().popBackStack(BACK_STACK_ROOT_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
    bottomNavigationView.setSelectedItemId(R.id.action_announcement); 
    } 
    else{ 
     // Close the application when we are on home fragment. 
     supportFinishAfterTransition(); 
    } 
} 
} 
0

これは多分少し遅れているが、私はそれを行うための最善の方法は、このような単純なことだと思います。

@Override 
public void onBackPressed() { 
    if (mBottomNavigationView.getSelectedItemId() == R.id.action_home) { 
     super.onBackPressed(); 
    } else { 
     mBottomNavigationView.setSelectedItemId(R.id.action_home); 
    } 
} 

私はそれはonBackPressedが私のために働いていなかった:)

0

をコーディングすることができますし、幸せを願っています。だから私はこれを使いました。

@Override 
protected void onResume() { 
    super.onResume(); 
    bottomNavigationView.getMenu().getItem(0).setChecked(true); 
} 
関連する問題