I have a bottom navigation bar with multiple elements that send me to different fragments .
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.navigation_pokemon_description:
selectedFragment = PokemonDescriptionFragment.newInstance(MainActivity.getSelectedPokemon().get_id());
break;
case R.id.navigation_pokemon_evolutions:
selectedFragment = PokemonEvolutionsFragment.newInstance();
break;
case R.id.navigation_pokemon_moves:
selectedFragment = PokemonMovesFragment.newInstance();
break;
case R.id.navigation_pokemon_breeding:
selectedFragment = PokemonBreedingTrainingFragment.newInstance();
break;
case R.id.navigation_pokemon_location:
selectedFragment = PokemonLocationFragment.newInstance();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});
All the fragments works fine except the Moves fragment , when I press it , it costs around 3 seconds to load the data and display the fragment .
I would like to show the fragment first and then , load the moves and show a progress bar or something like that while the data is loading .
This is my fragment :
public class PokemonMovesFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
databaseAccess = DatabaseAccess.getInstance(getContext());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_pokemon_moves, container, false);
this.view=view;
initalizeAllComponents();
initializePokemonData();
initializePostDataPopulationComponents();
getActivity().setTitle(getResources().getText(R.string.moves)+ " (" +selectedPokemon.getName() + ")");
return view;
}
//The rest of the methods
Simply move all your logic inside onViewCreated, then show Progressbar before the logic and hide Progressbar after the logic
#Override
public View onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState)
progressBar.visibility = View.VISIBLE; // Show Progress bar here
initalizeAllComponents();
initializePokemonData();
initializePostDataPopulationComponents();
getActivity().setTitle(getResources().getText(R.string.moves)+ " (" +selectedPokemon.getName() + ")");
progressBar.visibility = View.INVISIBLE; // Hide Progress bar here
}
Related
I have ,
Two fragments (Fragment1,Fragment2).
Two buttons (Btn1 in frag1 , Btn2 in frag2).
A bottom navigation view.
On clicking the Btn in frag1 , we will be directed to frag2.
On clicking the Btn in frag2 , we will be directed to frag1.
while directing from frag(1->2 or 2->1), the icon on the bottom navigation view stays the same
Is there a way to highlight that icon with respect to the loaded fragment?
On Click Listener for btn in frag1
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.body_container, new Fragment2()).commit();
On Click Listener for btn in frag2
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.body_container, new Fragment1()).commit();
OnItemSelectedListener for bottom nav in MainActivity Code
((BottomNavigationView)findViewById(R.id.bottom_nav)).setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener(){
Fragment clickedFragment = null;
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.one: clickedFragment = new Fragment1(); break;
case R.id.two: clickedFragment = new Fragment2(); break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.body_container, clickedFragment).commit();
return true;
}
});
The setOnItemSelectedListener is only triggered whenever the selected item of the BottomNavigationView changes. What you are currently doing is changing the current displayed fragment. Instead of changing the fragment, you should set the selected item of the BottomNavigationView instead. Something like this should work
((BottomNavigationView) findViewById(R.id.bottom_nav)).setSelectedItemId(R.id.your_menu_item_id);
Create a class temp in the same package as the main activity is in and add the below field to it.
public static BottomNavigationView bottomNavigationView;
Just go through the code, I explained in comments.
Main Activity Code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavView = temp.bottomNavigationView = findViewById(R.id.bottom_nav);
//This line, initially when the app is opened, displays the fragment1 by default
getSupportFragmentManager().beginTransaction().replace(R.id.body_container, new Fragment1()).commit();
bottomNavView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment clickedFragment = null;
switch (item.getItemId()) {
case R.id.one: clickedFragment = new Fragment1(); break;
case R.id.two: clickedFragment = new Fragment2(); break;
}
//This line replaces the fragment when user clicks on icon of bottom navigation view
getSupportFragmentManager().beginTransaction().replace(R.id.body_container, clickedFragment).commit();
return true;
}
});
}
3.OnViewCreated in Fragment1
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_to_frag2).setOnClickListener(l->{
temp.bottomNavigationView.setSelectedItemId(R.id.two);
});
}
4.OnViewCreated in Fragment2
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_to_frag1).setOnClickListener(l->{
temp.bottomNavigationView.setSelectedItemId(R.id.one);
});
}
Just make sure that the setOnItemSelectedListener has a return value of true
It works fine without setting the setSelectedItemId
this is the web view fragment
public class Home extends Fragment {
public Home() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_home, container, false);
WebView webView = (WebView)v.findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://www.google.com");
return v;
}
}
I created web view inside other fragment not in main activity and when I press back button the app will close. so how to go back only inside web view (not through fragments)? please give me a solution.
here is my main activity
public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
private static final String TAG = "MainActivity";
BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigationView = findViewById(R.id.bottom_navigation_view);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
bottomNavigationView.setSelectedItemId(R.id.navigation_home);
}
Home homeFragment = new Home();
Live_And_Event_Schedule live_and_event_scheduleFragment = new Live_And_Event_Schedule();
Photos photosFragment = new Photos();
Videos videosFragment = new Videos();
About aboutFragment = new About();
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.navigation_home:
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out).replace(R.id.center, homeFragment).commit();
return true;
case R.id.navigation_live_and_event_schedule:
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out).replace(R.id.center, live_and_event_scheduleFragment).commit();
return true;
case R.id.navigation_photos:
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out).replace(R.id.center, photosFragment).commit();
return true;
case R.id.navigation_videos:
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out).replace(R.id.center, videosFragment).commit();
return true;
case R.id.navigation_about:
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out).replace(R.id.center, aboutFragment).commit();
return true;
}
return false;
}
}
you can override onBackPressed in the Activity. save all fragmentTransaction before addToBackStack
#Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//add extra code
} else {
getSupportFragmentManager().popBackStack();
}
}
I am using Bottom Navigation Layout to show 5 fragments but the problem is after every onResume is called each fragment start lagging more and more.
This is my main activity with contain bottom navigation
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menu_home:
if (!selectedFragment.equalsIgnoreCase(Consts.MasterHomeFragment)) {
openMasterHomeFragment();
}
break;
case R.id.menu_wallet:
if (!isSessionActive()) {
showLoginBottomDialog();
return false;
} else {
if (!selectedFragment.equalsIgnoreCase(Consts.WalletFragment))
openWalletFragment();
}
break;
case R.id.menu_portfolio:
if (!isSessionActive()) {
showLoginBottomDialog();
return false;
} else {
if (!selectedFragment.equalsIgnoreCase(Consts.PortfolioFragment))
openPortfolioFragment();
}
break;
on each method i do
public void openPortfolioFragment() {
eventTracker.track(EventTracker.HOME_PORTFOLIO_NAV_CLICKED);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
PortfolioFragment portfolioFragment = new PortfolioFragment();
transaction.replace(R.id.activity_home_main_frame, portfolioFragment);
transaction.commit();
selectedFragment = Consts.PortfolioFragment;
}
public void openProfileFragment() {
eventTracker.track(EventTracker.HOME_ACCOUNT_NAV_CLICKED);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
ProfileFragment profileFragment = new ProfileFragment();
transaction.replace(R.id.activity_home_main_frame, profileFragment);
transaction.commit();
selectedFragment = Consts.ProfileFragment;
}
and oneach fragment onresume calling api
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_wallet, container, false);
unbinder = ButterKnife.bind(this, view);
initViewPager(view);
return view;
}
#Override
public void onResume() {
super.onResume();
loadDataFromApi();
}
and rendering data
#Override
public void onDataLoaded(MasterHomeResponse response) {
if (getActivity() != null && isAdded()) {
masterHomeResponse = response;
hideRefreshing();
initPortfolio(response);
initInbox(response.getInbox());
initAssets(response);
initTutorial(response);
initFeeds(response);
showBottomMoreFloatingButton();
boolean dismissIntro = sharedPreferenceHelper.getSamplePreference().getShowCase();
showGuideView(response, dismissIntro);
}
}
when ever i go to background and come back to application every fragment start lagging on scrolling
I was searching solution for this issue i have got this link Android Facebook SDK lowers app performance me also using facebook sdk for login purpose so making autologging value to false my issue resolved.
I have an Activity that is holding a main Fragment which then contains a ViewPager and TabLayout. I have implemented a NavigationDrawer i my MainActivity and want to change the viewPager.setCurrentItem when the user clicks an Item in the NavigationDrawer.
How can I pass the data from the NavigationDrawer in my MainActivity, to the ViewPager which is in my Fragment?
Main Activity:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
//TODO: handle the item clicks in navDrawer
switch (menuItem.getItemId()) {
case R.id.nav_home:
// Here I want to call viewPager.setCurrentItem(0), but I cannot call this from here.
Toast.makeText(NITrafficActivity.this, "Home!", Toast.LENGTH_SHORT).show();
break;
case R.id.nav_cctv:
Toast.makeText(NITrafficActivity.this, "CCTV Cameras", Toast.LENGTH_SHORT).show();
break;
case R.id.nav_future_roadworks:
Toast.makeText(NITrafficActivity.this, "Future Roadworks", Toast.LENGTH_SHORT).show();
break;
case R.id.nav_journey_times:
Toast.makeText(NITrafficActivity.this, "Journey Times", Toast.LENGTH_SHORT).show();
break;
case R.id.nav_speed_cameras:
Toast.makeText(NITrafficActivity.this, "Speed Cameras", Toast.LENGTH_SHORT).show();
break;
}
menuItem.setChecked(true);
drawerLayout.closeDrawers();
return true;
}
Main Fragment:
public class TrafficTabsFragment extends Fragment implements OnBackPressedHandler {
private MyViewModel viewModel;
private SearchView searchView;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
viewModel = ViewModelProviders.of(requireActivity()).get(MyViewModel.class);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_traffic_tabs, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final List<Pair<String, Fragment>> tabs = CollectionsKt.arrayListOf(
new Pair<String, Fragment>(getString(R.string.roadworks, 0), RoadworksFeedFragment.newInstance()),
new Pair<String, Fragment>(getString(R.string.incidents, 0), IncidentsFeedFragment.newInstance())
);
tabLayout = view.findViewById(R.id.main_tab_layout);
viewPager = view.findViewById(R.id.main_view_pager);
viewPager.setAdapter(new TrafficTabsAdapter(getChildFragmentManager(), tabs));
tabLayout.setupWithViewPager(viewPager);
monitorFilterCount(viewModel.roadworksFilterCount, 0, R.string.roadworks);
monitorFilterCount(viewModel.incidentsFilterCount, 1, R.string.incidents);
}
You can pass position to fragment from its reference.
Inside your TrafficTabsFragment,add this method.
public void changeItem(int position){
viewPager.setCurrentItem(position,true);
}
Inside onNavigationItemSelected callback,call changeItem method passing position argument.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
//TODO: handle the item clicks in navDrawer
switch (menuItem.getItemId()) {
case R.id.nav_home:
//call it here
trafficTabFragment.changeItem(0);
break;
case R.id.nav_cctv:
trafficTabFragment.changeItem(1);
break;
case R.id.nav_future_roadworks:
trafficTabFragment.changeItem(2);
break;
case R.id.nav_journey_times:
trafficTabFragment.changeItem(3);
break;
case R.id.nav_speed_cameras:
trafficTabFragment.changeItem(4);
break;
}
menuItem.setChecked(true);
drawerLayout.closeDrawers();
return true;
}
I am using the library com.roughike:bottom-bar:1.2.1 to make an Android app using bottom tabs. The problem is that in his github, there is no actual example on how tabs work with fragments. I have tried to work my way around it but to no success. Here is the code below.
public class MainActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.three_buttons_activity);
BottomBar bottomBar = BottomBar.attach(this, savedInstanceState);
bottomBar.setItemsFromMenu(R.menu.three_buttons_menu, new OnMenuTabSelectedListener() {
#Override
public void onMenuItemSelected(int itemId) {
switch (itemId) {
case R.id.recent_item:
//Snackbar.make(coordinatorLayout, "Recent Item Selected", Snackbar.LENGTH_LONG).show();
break;
case R.id.favorite_item:
//Snackbar.make(coordinatorLayout, "Favorite Item Selected", Snackbar.LENGTH_LONG).show();
break;
case R.id.location_item:
//Snackbar.make(coordinatorLayout, "Location Item Selected", Snackbar.LENGTH_LONG).show();
break;
}
}
});
bottomBar.setActiveTabColor("#FFFFFF");
}
}
I wanted to have for example if I choose "recent item" it will go to recent item tab and do whatever on that tab but it doesn't happen to me.
If any of you have a good suggestion and example on how to do it right, I will really appreciate it..
Thanks
I used this bottom bar over a year ago. this is how i added the fragments.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three_buttons);
// ************* Setting Up The Bottom Bar ************ //
BottomBar bottomBar = BottomBar.attach(this, savedInstanceState);
bottomBar.noTabletGoodness();
// *********** Adding Item Fragments to the bottom Bar ************ //
bottomBar.setFragmentItems(getSupportFragmentManager(), R.id.fragmentContainer,
new BottomBarFragment(ProfileFragment.newInstance("Content For Profile"), R.drawable.ic_profile, "Profile"),
new BottomBarFragment(MessagesFragment.newInstance(), R.drawable.ic_chat, "Messages"));
// bottomBar.setActiveTabColor("#009688");
bottomBar.setActiveTabColor(getResources().getColor(R.color.blue));
}
And one of the Fragment Class:
public class ProfileFragment extends Fragment {
public static ProfileFragment newInstance(String text) {
Bundle args = new Bundle();
args.putString(STARTING_TEXT, text);
ProfileFragment homeFragment = new ProfileFragment();
homeFragment.setArguments(args);
return homeFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_profile_fragment, container, false);
// do your stuff
return rootView;
}