i used this GitHub library in my code for bottom navigation.chip navigation bar
i tried to make it floating up after starting the program.but when run the program it is disappeared but when clicking in the buttons place . on click listener works but i couldn't see the navigation bar
this is the click listener ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btmNav = findViewById(R.id.btmNav);
layout = findViewById(R.id.cntBTM);
animMove = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_up);
btmNav.startAnimation(animMove);
//////////////*
if (savedInstanceState == null) {
NewsFragment newsFragment = new NewsFragment();
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, newsFragment)
.commit();
}
btmNav.setOnItemSelectedListener(new ChipNavigationBar.OnItemSelectedListener() {
#Override
public void onItemSelected(int id) {
Fragment fragment = null;
switch (id) {
case R.id.home:
fragment = new WebFragment();
break;
case R.id.activity:
fragment = new ActivityFragment();
break;
case R.id.settings:
fragment = new SettingFragment();
break;
}
if (fragment != null) {
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, fragment)
.commit();
} else {
Log.e(TAG, "Error in creating fragment");
}
}
});
and this in main activity
<com.ismaeldivita.chipnavigation.ChipNavigationBar
android:id="#+id/btmNav"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_margin="12dp"
android:background="#drawable/rounded"
android:elevation="5dp"
android:outlineAmbientShadowColor="#color/colorAccent"
app:cnb_menuResource="#menu/bottom_menu"
app:cnb_unselectedColor="#fff"
Use this library https://github.com/ismaeldivita/chip-navigation-bar
Dont forget to add maven in settings.graddle
maven { url 'https://jitpack.io' }
And dont forget to add this dependency to your build.graddle file
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
add your build.gradle implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.72'
Related
I have 3 and more fragments and I want to access them with the drawer.
So that when I click on "Profile" the current fragment(i.e. Home) should hide and "Profile" fragment should show and vice versa..
Right now its working with "replace fragment" but,
Instead of replace I want to show/hide them when I click on the drawer button.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//my coding
replace(new HomeFragment());
init();
}
private void init() {
mDrawer = (FlowingDrawer) findViewById(R.id.drawerlayout);
iv_Menu = findViewById(R.id.iv_Menu);
ll_Home = findViewById(R.id.ll_Home);
ll_Profile = findViewById(R.id.ll_Profile);
ll_Setting = findViewById(R.id.ll_Setting);
ll_Share = findViewById(R.id.ll_Share);
ll_Logout = findViewById(R.id.ll_Logout);
iv_Menu.setOnClickListener(this);
ll_Home.setOnClickListener(this);
ll_Profile.setOnClickListener(this);
ll_Setting.setOnClickListener(this);
ll_Share.setOnClickListener(this);
ll_Logout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.iv_Menu:
mDrawer.openMenu(true);
break;
case R.id.ll_Home:
replace(new HomeFragment(),"Home");
mDrawer.closeMenu(true);
break;
case R.id.ll_Profile:
replace(new ProfileFragment(),"Profile");
mDrawer.closeMenu(true);
break;
case R.id.ll_Setting:
startActivity(new Intent(this, SimplPreach.class));
mDrawer.closeMenu(true);
break;
case R.id.ll_Share:
Toast.makeText(this, "Share.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
case R.id.ll_Logout:
Toast.makeText(this, "Logout.", Toast.LENGTH_SHORT).show();
mDrawer.closeMenu(true);
break;
}
}
private void replace(Fragment fragment, String s) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.addToBackStack(s);
transaction.commit();
}
private void replace(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fl_Main,fragment);
transaction.commit();
}
I have been searching from hours but nothing is working,
How can I use show hide instead of replace ..
Please help me..
FragmentTransaction has the following methods you can use.
show(Fragment fragment)
hide(Fragment fragment)
add(int containerViewId, Fragment fragment, String tag)
And I think you don't need to call transaction.addToBackStack(s) in your case.
In my application I have NavigationView and into this NavigationView I have set menu for open some fragments!
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="320dip"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#000"
android:fitsSystemWindows="true"
app:headerLayout="#layout/tester_drawer_header"
app:itemIconTint="#fff"
app:itemTextColor="#fff"
app:menu="#menu/tester_drawer_main"/>
I want when click on this menu open one fragment and I want when go to nested fragments and press onBack button open first fragment not open backStack fragments!
I write below codes, but after click on back button back fragments from backStack, but I want just open first fragment!
MyActivity codes:
public class TesterDashboardActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tester_dashboard);
loadFragment(new TesterTestListFragment(), userName);
}
#Override
public void onBackPressed() {
fragmentBackCount = getSupportFragmentManager().getBackStackEntryCount();
if (fragmentBackCount <= 1) {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
//finishAffinity();
super.onBackPressed();
}
} else {
getSupportFragmentManager().popBackStack();
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.nav_home:
loadFragment(new TesterTestListFragment(), userName);
break;
case R.id.nav_billing:
loadFragment(new TesterFinanceFragment(), context.getString(R.string.menu_billing));
break;
case R.id.nav_edit_profile:
loadFragment(new TesterProfileFilterEditFragment(), context.getString(R.string.menu_edit_profile));
break;
case R.id.nav_bank:
loadFragment(new TesterShebaFragment(), context.getString(R.string.menu_bank));
break;
case R.id.nav_report:
loadFragment(new TesterReportsFragment(), context.getString(R.string.menu_report));
break;
case R.id.nav_setting:
loadFragment(new TesterSettingFragment(), context.getString(R.string.menu_setting));
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void loadFragment(Fragment fragment, String toolbarTitle) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.testerFragment, fragment,TAG_FRAGMENT);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
toolbar.setTitle(toolbarTitle);
}
How can I fix it?
In your code I found when the fragmentBackCount>1 you just call getSupportFragmentManager().popBackStack(); once, so you will see top fragment on backstack.
I think you should call getSupportFragmentManager().popBackStack();, fragmentBackCount-1 time to reach the first fragmnet
else {
for(int i=0;i<fragmentBackCount-1;i++)
getSupportFragmentManager().popBackStack();
}
When you are transitioning between Fragments, call addToBackStack() as part of your
FragmentTransaction:
FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag" ).commit();
I have an issue with onBackPressed() implementation in my app. I have a single fragment with differents tags. The user could navigate between fragments with a Navigation View and the back button. Everything works as expected except when FragmentTransaction goes like this:
Initial Fragment->A->B->C->A
When I use back button to return, the behavior I want to achieve is A->C->B->Initial.
Instead, I get A->B->C->A->Initial
How can I acomplish my desired behavior?
This is what I have so far:
private int backStackEntries = 0;
public void onBackPressed() {
Log.d(TAG,"Number of fragments in back: "+backStackEntries);
NewsListFragment fragment = (NewsListFragment) getSupportFragmentManager().findFragmentByTag(currentFrag);
backStackEntries-=1;
if(backStackEntries<0)
backStackEntries = 0;
if(fragment.getTag().equals(News_TAG[0])){
if(fragment.getParserMaker().isRunning()){
moveTaskToBack(true);
}
else{
finish();
}
}
else{
currentFrag = getSupportFragmentManager().getBackStackEntryAt(backStackEntries).getName();
getSupportFragmentManager().beginTransaction()
.hide(fragment)
.show(getSupportFragmentManager().findFragmentByTag(currentFrag))
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
}
}
private void makeFragmentTransaction(String[] urls, int item,String _TAG) {
Bundle bundle = new Bundle();
bundle.putStringArray("urls", urls);
NewsListFragment newsFragment = (NewsListFragment) getSupportFragmentManager().findFragmentByTag(_TAG);
if(newsFragment == null){
newsFragment = new NewsListFragment();
}
newsFragment.setArguments(bundle);
if(currentFrag == null){
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, newsFragment, _TAG)
.addToBackStack(_TAG)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
currentFrag = _TAG;
}
else if(!newsFragment.isAdded()){
getSupportFragmentManager().beginTransaction()
.hide(getSupportFragmentManager().findFragmentByTag(currentFrag))
.add(R.id.container,newsFragment,_TAG)
.addToBackStack(_TAG)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
currentFrag = _TAG;
backStackEntries+=1;
}
else if(!currentFrag.equals(_TAG)){
getSupportFragmentManager().beginTransaction()
.hide(getSupportFragmentManager().findFragmentByTag(currentFrag))
.show(newsFragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
backStackEntries+=1;
currentFrag = _TAG;
}
navigationView.setCheckedItem(item);
drawerLayout.closeDrawers();
}
Adding the last backStackEntries+=1; makes the weird behavior and erasing that line makes the deal BUT it creates another Transaction issue:
Initial(going back)->B->C
Pressing back button: C->Initial
I have also tried making transactions like this:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, newsFragment, _TAG)
.addToBackStack(_TAG)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
currentFrag = _TAG;
And onBackPressed like this:
NewsListFragment fragment = (NewsListFragment) getSupportFragmentManager().findFragmentByTag(currentFrag);
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
if (fragment.getParserMaker().isRunning()) {
moveTaskToBack(true);
} else {
finish();
}
}
This also cause the undesired behavior and popBackStack() removes fragment, which I don't want to do.
I also had the same problem, I solved it by implementing my own history stack for the fragments. everytime that I wanted to add a fragment to the stack, I would look through the stack and removed the fragment with the same class as the one I was gonna add (if there was one)
I'm confused how to open my different fragments by clicking on one Item in my navigation drawer.
In MainActivity I use the following Code:
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment;
int id = item.getItemId();
if (id == R.id.nav_listview) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, new ListFragment());
ft.commit();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
First of all I want to try to open my ListFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
}
In my content main.xml I created the following fragment which should be replaced when clicking on the specific Items in the Navigation Drawer.
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment" />
But it isnt working...
Can anyone help me?
Rastaman
To get what you want try this ,I was also held up with this somewhat complex looking code but its more of a easy way to use
Here's detailed explanation and walk through to this issue:
(Its seems Long But You can easily relate your work asap)
When you first create the Navigation Drawer Activity, there are 5 files we’ll look at:
MainActivity.java - this is the code behind for everything in our app.
activity_main.xml - this is the layout for the app including the nav drawer and an include for the app_bar_main.
app_bar_main.xml - this is the layout with the toolbar (at the top), a floating action button (at the bottom right), and an include for content_main.
content_main.xml - this is the layout for the content of the main page.
nav_header_main.xml - this is the UI for the top part of the nav drawer.
Step 1:
open up the app_bar_main.xml, comment out the include and add a new FrameLayout:
<!--<include layout="#layout/content_main" />-->
<FrameLayout
android:id="#+id/Fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
This FrameLayout is what we’ll use to load our fragments into.
Step 2:
Next, you’ll want to add a few fragments
To do so, right click on your project, or go to File –> New and from the Fragment list choose Fragment (Blank) or others
Step 3:
The next step is to load a fragment when the app first launches. Go to the MainActivity’s onCreate method and put the following in after the call to setSupportActionBar:
Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = FragmentOne.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.Fragment_container, fragment).commit();
Step 4:
You’ll then need to add OnFragmentInteractionListener to the interfaces your MainActivity implements and also implement the onFragmentInteraction method.Like this
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, FragmentOne.OnFragmentInteractionListener ,FragmentTwo.OnFragmentInteractionListener,FragmentThree.OnFragmentInteractionListener {
Step 5:
Finally, in the onNavigationItemSelected method, you can add the ability to load different fragments when menu items are tapped:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
Class fragmentClass = null;
if (id == R.id.nav_camera) {
fragmentClass = FragmentOne.class;
} else if (id == R.id.nav_gallery) {
fragmentClass = FragmentTwo.class;
} else if (id == R.id.nav_slideshow) {
fragmentClass = FragmentThree.class;
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Here I’m just loading one of the two fragments I’ve added to my app. Note that because I have two different fragments, I had to implement the interfaces for both FragmentOne.OnFragmentInteractionListener and FragmentTwo.OnFragmentInteractionListener.
That’s all you need to do to implement fragment loading in your Navigation Drawer.
What the user taps a menu item, the drawer will slide back in smoothly and the new fragment will have already started / finished loading. This also prevents any possible jankiness that you could see when launching a new activity.
EXTRA
One last thing to note is that if you switch to a different fragment and then rotate the device or cause another recreation of the activity, the code above will cause the first fragment to be reloaded. One easy way to deal with that is to wrap the fragment block in the onCreate method in a check to see if the savedInstanceState is not null like this:
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState == null) {
//Fragment load code
}
...
}
Try this Code
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment=null;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int id = item.getItemId();
if (id == R.id.nav_listview) {
fragment= new ListFragment();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/container" />
Please Change The name of your fragment class ListFragment Because ListFragment is already Sub Class of Fragments in android.app package android OS
Mhmm I found an answer. But I am confused.
If I use:
if (id == R.id.nav_listview) {
fragment= new com.thomas.testapp.ListFragment();
It works. But I only have to use the package name if I want to open my ListFragment. Why?
I suggest to Create codes More Dynamic
first of all, if you have custom class to create Navigation Drawer, use listener to call methods from your activity
there is class call HomeFragment extends Fragment, so we have :
if(condition){
fragment = new HomeFragment();
// if there is Listener
if(mListener != null){
mListener.someMethod
}
// Other Settings And Codes
}
public class MainActivity extends AppCompatActivity {
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...From section above...
// Find our drawer view
nvDrawer = (NavigationView) findViewById(R.id.nvView);
// Setup drawer view
setupDrawerContent(nvDrawer);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
selectDrawerItem(menuItem);
return true;
}
});
}
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
fragmentClass = FirstFragment.class;
break;
case R.id.nav_second_fragment:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_third_fragment:
fragmentClass = ThirdFragment.class;
break;
default:
fragmentClass = FirstFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
mDrawer.closeDrawers();
}
// ...
}
I currently have a MainActivity.java which should be the only activity class. Though in that activity class I have a nav-drawer which links to other fragment views.
Currently the main issue Im facing is implementing tabs under a fragment and making them just be available for only that fragment and subfragments. I ran my application and the tabs appeared, but they also appear on other fragments after I visit the TeamsAndDriversFragment.
In my MainActivity.java I have the following function which helps point to the fragments it will generate once someone clicks on them in the nav-drawer:
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new TimeAndScoringFragment();
break;
case 1:
fragment = new ScheduleFragment();
break;
case 2:
fragment = new StandingsFragment();
break;
case 3:
fragment = new TeamsAndDriversFragment();
break;
case 4:
fragment = new NewsFragment();
break;
default:
break;
}
if (fragment != null) {
// Create a fragment transaction object to be able to switch fragments
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
Here is my current TeamsAndDriversFragment class where I have an actionbar navigation with tabs:
public class TeamsAndDriversFragment extends Fragment implements TabListener {
private List<Fragment> fragList = new ArrayList<Fragment>();
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
ActionBar bar = getActivity().getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab mTeamsTab = bar.newTab();
mTeamsTab.setText("Teams");
mTeamsTab.setTabListener(this);
bar.addTab(mTeamsTab);
Tab mDriversTab = bar.newTab();
mDriversTab.setText("Drivers");
mDriversTab.setTabListener(this);
bar.addTab(mDriversTab);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Fragment f = null;
TabFragment tf = null;
if(fragList.size() > tab.getPosition()) {
fragList.get(tab.getPosition());
}
if(f == null) {
tf = new TabFragment();
Bundle data = new Bundle();
data.putInt("idx", tab.getPosition());
tf.setArguments(data);
fragList.add(tf);
} else {
tf = (TabFragment) f;
}
ft.replace(android.R.id.content, tf);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if(fragList.size() > tab.getPosition()) {
ft.remove(fragList.get(tab.getPosition()));
}
}
}
In the displayView() method simply remove all tabs from the ActionBar, this way you'll always have a clean ActionBar with the exception of the TeamsAndDriversFragment fragment:
private void displayView(int position) {
getSupportActionBar().removeAllTabs();
// ...
}