We have bottom navigation tabs(4) and each tab is having fragment in it. Could anyone help(give idea) how to design the structure in MVVM way with keeping the fragment state for each tab. I know that this is not the place for poor questions but I am looking for conceptual advice. To accomplish it in a best possible way.
With the latest arch components life become so much easer.
Now I don't have to care about keeping my fragments alive as long as I implement business logic (state) inside ViewModel i am fine. It survives the config changes.
If you ask me how about when system kills your app in order to claim the memory,
with latest ViewModel feature you can manage this inside you ViewModel. So you can eliminate extra boilerplate code/communication code between View and ViewModel to pass savedState (e.g id, url, etc..). This would be true separation of concern.
Google (through Nick Butcher‏) announced the release of the v25 of the Android Design Support Library which includes the new BottomNavigationView.
menu.xml
Define navigation items (Fragments items) in the menu resource file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_item1"
android:icon="#drawable/icon1"
android:title="Menu1"
/>
<item
android:id="#+id/action_item2"
android:icon="#drawable/icon2"
android:title="Menu2"/>
<item
android:id="#+id/action_item3"
android:icon="#drawable/icon3"
android:title="Menu3" />
<item
android:id="#+id/action_item4"
android:icon="#drawable/icon4"
android:title="Menu4" />
</menu>
activity_main.xml
ADD the actual BottomNavigationView to the layout.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="#color/colorPrimary"
local:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<FrameLayout
android:id="#+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/navigation"
android:layout_below="#id/toolbar"
android:animateLayoutChanges="true">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/rbtn_selector"
android:paddingTop="#dimen/_2sdp"
app:itemIconTint="#drawable/selector_bottom"
app:itemTextColor="#drawable/selector_bottom"
app:elevation="#dimen/_8sdp"
app:menu="#menu/menu"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
bottomNavigationView = (BottomNavigationView)findViewById(R.id.navigation);
//If you want to remove slide animation of bottomview with Helper Class
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
Menu m = bottomNavigationView.getMenu();
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}
android.app.Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_item1:
selectedFragment = Fragment1.newInstance();
toolbar.setTitle("Fragment1");
break;
case R.id.action_item2:
selectedFragment = Fragment2.newInstance();
toolbar.setTitle("Fragment2");
break;
case R.id.action_item3:
selectedFragment = Fragment3.newInstance();
toolbar.setTitle("Fragment3");
break;
case R.id.action_item4:
selectedFragment = Fragment4.newInstance();
toolbar.setTitle("Fragment4");
break;
default:
selectedFragment = Fragment1.newInstance();
toolbar.setTitle("Fragment1");
break;
}
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});
//Manually displaying the first fragment - one time only
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, Fragment1.newInstance());
transaction.commit();
}
This Helper class for Remove Shifting animation
static class BottomNavigationViewHelper {
public static void removeShiftMode(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);
item.setShiftingMode(false);
// set once again checked value, so view will be updated
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
} catch (IllegalAccessException e) {
Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
}
}
}
Each Fragment as a menu item **Fragmen1.java**
public class Fragmen1 extends android.app.Fragment {
public static Fragmen1 newInstance() {
Fragmen1 fragment = new Fragmen1();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
}
Related
I make use of BottomNavigationView in the current project I do. I have four fragments. This is a SpeedTest app. If I try to switch to another Fragment while the speed test is running, the app crashes. What I think is to disable the Bottombar while it's running. But I don't know how to do it. Is there any way to do this?
This is the Main Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
bottomNav.setOnNavigationItemSelectedListener(navListener);
if (savedInstanceState == null){
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new SpeedFragment()).commit();
}
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener = new
BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.nav_speed:
selectedFragment=new SpeedFragment();
break;
case R.id.nav_web:
selectedFragment=new WebFragment();
break;
case R.id.nav_video_test:
selectedFragment=new VideoFragment();
break;
case R.id.nav_history:
selectedFragment=new HistoryFragment();
break;
}
assert selectedFragment != null;
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
return true;
}
};
}
This is activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_navigation"
android:background="?android:attr/windowBackground"
app:labelVisibilityMode="labeled"/>
You can disable bottomNavigationBar like below:
bottomNavigationBar.setEnabled(false);
or you can also hide bottomNavigationBar like below:
bottomNavigationBar.setVisibility(View.GONE);
Just had to declare
BottomNavigationView bottomNav;
this as a global variable
and put
bottomNav = getActivity().findViewById(R.id.bottom_navigation);
inside OncreateView()
You need to disable each menu item separately:
for (i in 0 until bottomNavigationView.menu.size()) {
mainBinding.bottomNavigationView.menu.getItem(i).isEnabled = false
}
Good Morning, I am a newbie programmer, and I use Navigation Drawer Android Studio Activity to start. Everything is ok when I compile, but when I use the app and click on the different options, nothing happens (I mean that the layout doesn't change and remain on the activity_main.xml). I look for other questions but (I think) no one has had my problem.
MainActivity:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Ma giusto a provare", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
switch(item.getItemId()) {
case R.id.nav_home:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit();
break;
case R.id.nav_gallery:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</android.support.constraint.ConstraintLayout>
activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_menu_camera"
android:title="#string/menu_home" />
<item
android:id="#+id/nav_gallery"
android:icon="#drawable/ic_menu_gallery"
android:title="#string/menu_Cultura" />
<item
android:id="#+id/nav_slideshow"
android:icon="#drawable/ic_menu_slideshow"
android:title="#string/menu_organizer" />
<item
android:id="#+id/nav_tools"
android:icon="#drawable/ic_menu_manage"
android:title="#string/menu_tools" />
</group>
<item android:title="Communicate">
<menu>
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="#string/menu_share" />
<item
android:id="#+id/nav_send"
android:icon="#drawable/ic_menu_send"
android:title="#string/menu_send" />
</menu>
</item>
</menu>
fragment_cultura.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cultura generale!"
tools:layout_editor_absoluteX="171dp"
tools:layout_editor_absoluteY="320dp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VVVVai!"
tools:layout_editor_absoluteX="161dp"
tools:layout_editor_absoluteY="403dp" />
</android.support.constraint.ConstraintLayout>
CulturaClass.java
public class CulturaClass extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_cultura,container,false);
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hello" />
</android.support.v4.widget.DrawerLayout>
Instead of R.id.fragment_container provide name for FrameLayout in activity_main.xml and pass that name while replacing fragment i.e.
case R.id.nav_home:
ft.replace(R.id.<name_of_framelayout>, new CulturaClass()).commit();
break;
case R.id.nav_gallery:
ft.replace(R.id.<name_of_framelayout>, new CulturaClass()).commit();
break;
This might work for you
Because you are replacing fragment with same class:
case R.id.nav_home:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit(); //Same Class
break;
case R.id.nav_gallery:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit(); //Same Class
break;
You can do this thing simple and easy way using common function or method and You never do mistake.
You have two option to use this One is using JAVA and second, is KOTLIN
The first Method I write below check this:
If you are using java, use like this method
First, create one function i.e name setFragment and pass the parameter Fragment class and second is a title (a Title is an optional if you use or not)
Declare the globally variable
private Fragment fragment = null;
//create function for replace fragment
private void setFragment(Fragment fragmentName, String title) {
fragment = fragmentName;
if (fragment != null) {
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.framelayout, fragment, fragment.getTag()).commit();
}
setTitle("Dashboard");
// Close the navigation drawer
drawerLayout.closeDrawers();
}
If you are using KOTLIN:
First, create one function i.e name openFragment and pass the parameter Fragment class and second is a title (a Title is an optional if you use or not)
Declare the globally variable
private var fragment: Fragment? = null
//create function for replace fragment
fun openFragment(fragmentClass: Fragment, titleName: String) {
//pass the current fragment class name which you replace
fragment = fragmentClass
//check first fragment is null or not
if (fragment != null) {
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.framelayout, fragment!!, fragment!!.tag).commit()
}
title = titleName // replace the titlename
//check the drawerLayout close or not
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
}
}
I would appreciate if someone could give me some pointers to solve my latest issue.
I have an activity with a CollapsingToolbarLayout. In an un-collapsed state Im unable to get the buttons to work. I do not know how to fix this issue. I have searched on stackoverflow before posting this, but I did not find any helpful tips.
Im posting here hoping for an answer
Thanks
This is my code!
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/app_background"
android:fitsSystemWindows="true"
tools:context="com.company.walt.activities.photos.PhotosAAAActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/backdrop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/ip_photo_header"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="#+id/love_music"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AAAAAA"
android:textColor="#android:color/white"
android:textSize="#dimen/ssi_txt_40sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BBBBBBBB"
android:textColor="#android:color/white"
android:textSize="#dimen/ssi_txt_20sp" />
</LinearLayout>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="#dimen/ssi_24dp"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabIndicatorColor="#color/white"
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/white" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
PhotosAAAActivity.java
public class PhotosAAAActivity extends AppCompatActivity {
//region WIDGETS
private AppBarLayout bAppBarLayout;
private CollapsingToolbarLayout bCollapsingToolbar;
private Toolbar bToolbar;
private TabLayout mTabLayout;
//endregion
//region VARS
private ViewPager mViewPager;
private PhotosPagerAdapter mPhotosPagerAdapter;
SharedPreferencesManager mSharedPreferences;
//endregion
/* ******************************************************************************************* */
//region THE ONCREATE
#Override
protected void onCreate(Bundle savedInstanceState)
{
//region Load Preferences
mSharedPreferences = new SharedPreferencesManager(this);
//endregion
//region Switching theme style
if (mSharedPreferences.getNightModeState() == true) {
setTheme(R.style.NightTheme);
} else {
setTheme(R.style.LightTheme);
}
//endregion
//region Super onCreate
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photos);
//endregion
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window w = getWindow(); // in Activity's onCreate() for instance
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
//region Calling Methods
setUpCollapsingToolbar();
setUpToolbar();
setViewPager();
//endregion
}
//endregion
private void setUpCollapsingToolbar() {
bCollapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
bCollapsingToolbar.setCollapsedTitleTextColor(getResources().getColor(R.color.white));
bAppBarLayout = (AppBarLayout) findViewById(R.id.appbar);
bAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
bCollapsingToolbar.setTitle("Post photos");
isShow = true;
} else if (isShow) {
bCollapsingToolbar.setTitle("");
isShow = false;
}
}
});
}
/* ******************************************************************************************* */
//region Used to create the toolbar on top
private void setUpToolbar() {
bToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(bToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("");
}
//endregion
/* ******************************************************************************************* */
//region Used to create the tab layout
private void setViewPager() {
mViewPager = (ViewPager) findViewById(R.id.pager);
mPhotosPagerAdapter = new PhotosPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPhotosPagerAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tab);
mTabLayout.setupWithViewPager(mViewPager);
}
//endregion
/* ******************************************************************************************* */
//region MATERIAL DRAWER
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.photo_category, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case android.R.id.home:
finish();
//Toast.makeText(PhotosAAAActivity.this, "GO BACK", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//endregion
}
UPDATE! - 2018-01-13
I figured out what is cousing the the issue but I still dont know fix this
The problem is that if I remove this code then the tabs won't show up, so it feels as if this ***** with me
The issue
//region Used to create the tab layout
private void setViewPager() {
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mPhotosPagerAdapter = new PhotosPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPhotosPagerAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tab);
mTabLayout.setupWithViewPager(mViewPager);
}
//endregion
There are two issues with your code, both related to the buttons you're trying to get to work.
First, with the home button (or the up button you need to activate it with actionBar before handling events with it. Add the following:
getSupportActionBar().setHomeButtonEnabled(true);
inside your setupToolbar method. You can now access the button using the code you've written under the case android.R.id.home:.
The second button has the same issue. You haven't added any logic to handle the button click. Let's say your button on the right has id="#+id/more". Now to define an action for it, you need to put a case with its id inside switch like,
case R.id.more:
//The action needed for the button
break;
try this.
in your activity
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
in your xml
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
//for menu you should give ids to that menu items in your menu file
//R.menu.photo_category and after that if you have 2 menu items
// you have to write listener for every single items for onClick like.
case R.id.item1:
finish();
break;
case R.id.item2:
finish();
break;
}
return true
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
//noinspection SimplifiableIfStatement
return super.onOptionsItemSelected(item);
}
Back Button on click listener.
I have been making an app which has a navigation drawer, but that navigation drawer isn't working with the switch case I've made. The id's are right.
For starters here's the shortened version of my code:
Here's my java class:
public class Image extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
//DRAWER LAYOUT
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView mNavigationView = (NavigationView) findViewById(R.id.nav_menu);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
#Override public boolean onNavigationItemSelected(MenuItem menuItem)
{ switch (menuItem.getItemId())
{
case(R.id.nav_account): Intent accountActivity = new Intent(getApplicationContext(), Welcome.class);
startActivity(accountActivity);
case(R.id.nav_exercises): Intent accountActivity1 = new Intent(getApplicationContext(), Video.class);
startActivity(accountActivity1);
case(R.id.nav_tips): Intent accountActivity2 = new Intent(getApplicationContext(), Image.class);
startActivity(accountActivity2);
}
return true;
} );
//Navigation Drawer
}
//FOR NAVIGATION DRAWER
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
//Navigation Drawer End
}
Here are the XML's:
navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/nav_account"
android:icon="#mipmap/ic_person_outline_black_24dp"
android:title="My Account" />
<item android:id="#+id/nav_settings"
android:icon="#mipmap/ic_settings_black_24dp"
android:title="Settings"/>
<item android:id="#+id/nav_exercises"
android:icon="#mipmap/ic_accessibility_black_24dp"
android:title="Exercises"/>
<item android:id="#+id/nav_tips"
android:icon="#mipmap/ic_face_black_24dp"
android:title="Tips"/>
<item android:id="#+id/nav_scheduler"
android:icon="#mipmap/ic_date_range_black_24dp"
android:title="My Schedule"/>
<item android:id="#+id/nav_info"
android:icon="#mipmap/ic_info_outline_black_24dp"
android:title="Info"/>
<item android:id="#+id/nav_logout"
android:icon="#mipmap/ic_input_black_24dp"
android:title="Logout"/>
</menu>
Here's where I apply the drawer:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.Welcome.Video"
android:id="#+id/drawerLayout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<VideoView
android:id="#+id/videoView"
android:layout_width="wrap_content"
android:layout_height="259dp" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="videoplay"
android:text="Play" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:menu="#menu/navigation_menu"
app:headerLayout="#layout/navigation_header"
android:layout_gravity="start"
android:id="#+id/nav_menu"
>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
What happens is when the navigation drawer, I click nav_exercises case but what shows is the view of the supposed to be for the nav_tips. I click back and then it goes to the exercises part. The TIPS is working just as it is.
But the EXERCISES part, it shows the TIPS view and then when you press "back" it goes to the right place. In other words it's somehow overlapping with the other view.
What did I do wrong? I'm sure the class and ID's are in the right places, I've checked for an hour really.
Any help is appreciated. Thank you very much!
you need to add break; otherwise every case will be executed
switch (menuItem.getItemId())
{
case(R.id.nav_account): Intent accountActivity = new Intent(getApplicationContext(), Welcome.class);
startActivity(accountActivity);
break;
//^^^
case(R.id.nav_exercises): Intent accountActivity1 = new Intent(getApplicationContext(), Video.class);
startActivity(accountActivity1);
break;
//^^^
case(R.id.nav_tips): Intent accountActivity2 = new Intent(getApplicationContext(), Image.class);
startActivity(accountActivity2);
break;// not needed at last but good practice
}
You need to break the switch case
like
switch (request.getMethod()) {
case Method.GET:
...
break;
case Method.DELETE:
...
break;
case Method.POST:
...
break;
case Method.PUT:
...
break;
default:
throw new IllegalStateException("Unknown method type.");
}
Hello member stackoverflow
porblem with bottomnavihationview
in my app I used BottomNavigationView with 4 item . it make my app easy and beauty
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation_view);
bottomNavigationView.inflateMenu(R.menu.menu_bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.action_one:
break;
case R.id.action_two:
FragmentTransaction manger= getSupportFragmentManager().beginTransaction();
pop_web_view pop3 =new pop_web_view();
pop3.show(manger,null);
break;
case R.id.action_three:
break;
case R.id.action_four:
break;
}
return false;
}
});
in activity_main :
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_anchorGravity="bottom"
android:paddingTop="560dp"
app:itemBackground="#color/colorDivider"
app:itemIconTint="#color/colorPrimaryDark"
app:itemTextColor="#color/colorPrimaryDark"
app:menu="#menu/menu_bottom_navigation" />
in menu xml :
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_one"
android:icon="#android:drawable/ic_secure"
android:title="One"/>
<item
android:id="#+id/action_two"
android:icon="#android:drawable/ic_dialog_info"
android:title="Two"/>
<item
android:id="#+id/action_three"
android:icon="#android:drawable/ic_dialog_email"
android:title="Three"/>
<item
android:id="#+id/action_four"
android:icon="#android:drawable/ic_popup_reminder"
android:title="Four"/>
</menu>
BUT I have problem Caused by:
java.lang.IllegalArgumentException: Maximum number of items supported by BottomNavigationView is 5. Limit can be checked with BottomNavigationView#getMaxItemCount()
The error said that maximum number of items supported by BottomNavigationView is 5.
And try to delete
bottomNavigationView.inflateMenu(R.menu.menu_bottom_navigation);
because you are already inflating it in
app:menu="#menu/menu_bottom_navigation"
And you are modifying it by calling
bottomNavigationView.inflateMenu(R.menu.menu_bottom_navigation);
The documentation says Existing items in the menu will not be modified or removed.
Check this documention
And check this answer
Implementation of BottomNavigationView has condition: when there is more than 3 items then use shift mode.
I know you accepted the current answer, but it's incomplete.
You added a menu in your XML to the BottomNavigationView, then you try to call inflateMenu(...), however, the documentation clearly says:
Existing items in the menu will not be modified or removed.
This means that you are adding menu items to this view, not replacing them.
What you can do to fix it is the following:
bottomNavigationView.getMenu().clear();
bottomNavigationView.inflateMenu(R.menu.menu_bottom_navigation);
Also it's worth mentioning that you do the same things twice: once in the XML (by adding app:menu="..." attribute to the layout item), once in the Java class by calling the inflateMenu(...) method. Delete either of them and it will work. Keep in mind though that if you want to change the menu items later dynamically, you'll need to clear the existing items the way I posted.
In my app I used BottomNavigationView with 2 item, but there are 4 items like this:
My XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/bottom_navigation_constraintlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
tools:context=".BottomNavigation">
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#android:color/holo_red_dark"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
and my code:
public class BottomNavigation extends AppCompatActivity {
private static final String TAG = "BottomNavigation";
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_navigation);
updateMenu();
} catch (Exception e) {
Log.e(TAG, "onCreate: ", e);;
}
}
#UiThread
private void updateMenu() {
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
if (bottomNavigationView != null) {
bottomNavigationView.inflateMenu(R.menu.navigation);
for (Integer i = 0;
i < bottomNavigationView.getMenu().size();
++i ) {
Log.i(TAG, "updateMenu: " + bottomNavigationView.getMenu().getItem(i).getItemId());
}
}
}
}
Delete either of them and it will work. thanks.