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
}
Related
I have a bottom navigation view and at the center of bottom navigation view I have a floating action button. I start fragments when click on bottom navigation view items and when click on float action button I start an activity. Fragments are loading correctly but when I click on fab button sometimes it run correctly but sometimes it gives error.
I think, it gives error because I try to load fragment in activity and then I try to open a different activity when a fragment loaded in activity. But I couldn't fix it.
Menu :
https://i.stack.imgur.com/V5auA.jpg
Relative Part of Main Activity :
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private Context context;
private SharedPreference sharedPreference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = MainActivity.this;
sharedPreference = SharedPreference.getInstance(context);
if (getIntent().hasExtra(Constants.SCREEN_TAG)) {
String type = getIntent().getStringExtra(Constants.SCREEN_TAG);
}
FloatingActionButton fabMainActivity = findViewById(R.id.fabMainActivity);
BottomNavigationView bnvMainActivity = findViewById(R.id.bnvMainActivity);
bnvMainActivity.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener);
loadFragment(new DiscoverFragment());
fabMainActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, PostJobActivity.class));
}
});
}
private BottomNavigationView.OnNavigationItemSelectedListener onNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment selectedFragment = null;
switch (menuItem.getItemId()){
case R.id.navigation_discover:
selectedFragment = new DiscoverFragment();
break;
case R.id.navigation_nearby:
selectedFragment = new NearbyFragment();
break;
case R.id.empty_menu:
break;
case R.id.navigation_notification:
selectedFragment = new NotificationFragment();
break;
case R.id.navigation_profile:
selectedFragment = new ProfileFragment();
break;
}
loadFragment(selectedFragment);
return true;
}
};
private void loadFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.flMainActivity, fragment);
fragmentTransaction.commit();
}
}
Main Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
tools:context=".Activity.MainActivity"
android:background="#color/app_background">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/rlTopBackgroundMainActivity"
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="#drawable/top_background"
android:layout_gravity="top">
<ImageView
android:id="#+id/ivLogoWithTextMainActivity"
android:layout_width="142dp"
android:layout_height="41dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="23dp"
android:layout_marginEnd="247dp"
android:layout_marginRight="247dp"
android:layout_marginBottom="17dp"
android:layout_centerVertical="true"
android:contentDescription="#string/terms_activity_logo_with_text"
android:src="#drawable/logo_with_text" />
<ImageView
android:id="#+id/ivMessagesMainActivity"
android:layout_width="33dp"
android:layout_height="41dp"
android:src="#drawable/message_icon"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:layout_marginEnd="20dp"
android:contentDescription="#string/messages_icon" />
</RelativeLayout>
<FrameLayout
android:id="#+id/flMainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/rlTopBackgroundMainActivity" />
</RelativeLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bnvMainActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:layout_gravity="bottom"
app:itemIconTint="#color/bottom_menu_color"
app:menu="#menu/bottom_navigation_menu"
app:labelVisibilityMode="unlabeled" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bapMainActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
app:itemIconTint="#color/bottom_menu_color"
app:labelVisibilityMode="unlabeled"
app:fabAlignmentMode="center"
app:fabCradleMargin="7dp"
app:elevation="0dp"
android:layout_gravity="bottom"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fabMainActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/purple_2"
app:tint="#android:color/white"
android:src="#drawable/post_job_icon"
app:layout_anchor="#id/bapMainActivity"
app:maxImageSize="35dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Relative Part of Post Job Activity : (Post Job Activity also in frame layout.)
public class PostJobActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_job);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
context = PostJobActivity.this;
btnBackToMainActivityPostJobActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(PostJobActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
});
}
#Override
public void onBackPressed() {
Intent intent = new Intent(PostJobActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
}
Error Message:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at androidx.fragment.app.FragmentTransaction.doAddOp(FragmentTransaction.java:161)
at androidx.fragment.app.BackStackRecord.doAddOp(BackStackRecord.java:179)
at androidx.fragment.app.FragmentTransaction.replace(FragmentTransaction.java:225)
at androidx.fragment.app.FragmentTransaction.replace(FragmentTransaction.java:200)
at dk.lejekspert.lejekspertrekrutter.Activity.MainActivity.loadFragment(MainActivity.java:133)
at dk.lejekspert.lejekspertrekrutter.Activity.MainActivity.access$000(MainActivity.java:58)
at dk.lejekspert.lejekspertrekrutter.Activity.MainActivity$3.onNavigationItemSelected(MainActivity.java:126)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:124)
at android.view.View.performClick(View.java:5723)
at android.view.View$PerformClick.run(View.java:22689)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6364)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Any idea to solve this problem?
Thanks.
Edit : I added a sentence to my bottom_navigation_menu.xml file to make not enable menu item below fab button.
<item
android:id="#+id/empty_menu"
app:showAsAction="always"
android:enabled="false"
android:title="#string/nearby" />
Also this code part is not necessary anymore.
case R.id.empty_menu:
break;
The issue happens when you call fragmentTransaction.replace(R.id.flMainActivity, fragment); with fragment = null.
Check the onNavigationItemSelected.
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment selectedFragment = null;
switch (menuItem.getItemId()){
//...
case R.id.empty_menu:
break; // <-- this case
}
loadFragment(selectedFragment);
return true;
In this case the selectedFragment is null.
Checking the screen in the question it seems that you are using in the BottomNavigationView a menuItem without icon exactly behind the FAB.
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.
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);
}
}
I was looking here some ways to do what i want, i tried some codes but nothen works. I have a app with bottom bar (3 itens), and i have one fragment for each one. The 3 fragments load a layout with webview (3 differents links, of course). What i want is switch between fragment and keep it in the background, beause when I leave fragment 1 to fragment 2, and i back to fragment 1, the fragment 1 load again, and i just want to keep it load, and the others fragments too. How can i do that ?
Thanks for the help !!
Activity Main XML
<LinearLayout
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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="bandeira.thalisson.appExample.MainActivity">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="#menu/navigation"/>
Main Activity Java
public class MainActivity extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.navigation_item1:
selectedFragment = Fragment1.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
return true;
case R.id.navigation_item2:
selectedFragment = Fragment2.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
return true;
case R.id.navigation_item3:
selectedFragment = Fragment3.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
//*Iniciar um fragmento junto com o aplicativo
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content, Fragment1.newInstance());
transaction.commit();
}
Fragment Example Java
public class Google extends Fragment {
public WebView myWebView;
public static Google newInstance() {
Googlefragment = new Google();
return fragment;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.webview, container, false);
myWebView = (WebView) rootView.findViewById(R.id.WebViewLayout);
myWebView.loadUrl("http://google.com/");
//*Ativar JavaScript
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
//*Forçar links para abrir no WebView ao invés do navegador
myWebView.setWebViewClient(new WebViewClient());
return rootView;
}
Fragment XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/WebViewLayout"/>
Instead of using replace everytime in your onNavigationItemSelected, use show and hide.
Programmatically create all the fragments probably in your onCreate and in your item selected method
instead of this
getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
you do
getSupportFragmentManager().beginTransaction().show(R.id.content, selectedFragment).commit();
and similarly for hiding
getSupportFragmentManager().beginTransaction().hide(R.id.content, selectedFragment).commit();
In this case, it will created only once(the first time), and subsequently will be just shown and hidden (think in terms of VISIBLE and GONE, not saying its the same, but similar)
I'm making an Android app that uses an appBarLayout with tabs in it and webViews that load an external URL underneath it. In the toolbar menu I want to add a refresh option that refreshes only the current tab. I couldn't figure out how to get it working in my specific case. I already tried this solution but when I press the refresh button, the app crashes.
EDIT: I think the only part I need to edit is if (id == R.id.action_refresh) in my MainActivity.java. But because I have 4 tabs (Tab0, Tab1 etc.) I think it shouldn't say Tab0.webview.reload();, but just the current tab which is open.
Here is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(3);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
//TODO
return true;
}
if (id == R.id.action_refresh) {
//What comes here?
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab0 tab0 = new Tab0();
return tab0;
case 1:
Tab1 tab1 = new Tab1();
return tab1;
case 2:
Tab2 tab2 = new Tab2();
return tab2;
case 3:
Tab3 tab3 = new Tab3();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab 0";
case 1:
return "Tab 1";
case 2:
return "Tab 2";
case 3:
return "Tab 3";
}
return null;
}
}
}
My activity_main.xml
<?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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.my.app.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
android:background="#android:color/holo_red_light">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#android:color/holo_red_light"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="#android:color/holo_red_light"
app:tabMode="scrollable" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
My Tab0.java
public class Tab0 extends Fragment {
WebView webview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.tab0, container, false);
webview = (WebView)rootView.findViewById(R.id.webview0);
webview.setWebViewClient(new WebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setBuiltInZoomControls(true);
CookieManager.getInstance().setAcceptCookie(true);
webview.loadUrl("https://www.google.com");
return rootView;
}
}
My tab0.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="com.my.app.MainActivity$SectionsPagerAdapter">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webview0"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Can someone help me with implementing the refresh button?
Thanks in advance
The WebView.reload() should be the way to go for you as mentioned in the post you refered.
If your app crash because of it then you probably do soemthing wrong. What is the crash error?
Use following in the onOptionsItemSelected method:
if (id == R.id.action_refresh) {
((WebView) mSectionsPagerAdapter.getItem(0).getView().findViewById(R.id.webview0)).reload();
return true;
}