I have the following XML layout
<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=".MainActivity">
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fabCradleMargin="20dp"
app:fabCradleVerticalOffset="10dp"
app:fabCradleRoundedCornerRadius="20dp"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="16dp"
android:background="#android:color/transparent"
app:menu="#menu/bottom_nav_menu" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="#id/bottomAppBar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The associated Java file is the following:
public class MainActivity extends AppCompatActivity {
BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigationView = findViewById(R.id.bottomNavigationView);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Here's a Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
My question is, I would like to assign an image source dynamically as well as an action based on which of the navigation fragment the user is on.
So when the app opens it would default to the fab button having a '+' which allows users to add items to list.
If they hit the setting nav button I would like for the image to be gear and if pressed it opens the user setting prefs.
I am just not sure how to achieve this?
UPDATE:
if (bottomNavigationView.getMenu().findItem(R.id.miHome).isChecked()) {
// Set icon image for FAB
fab.setImageResource(R.drawable.ic_add);
} else if (bottomNavigationView.getMenu().findItem(R.id.miSettings).isChecked()) {
fab.setImageResource(R.drawable.ic_settings);
fab.setBackgroundColor(Color.RED);
}
The behavior is that it will show the + sign on load, since the dashboard is the default at app launch, but when I hit the settings nav button, the FAB icon does NOT change to the gear and the background color does NOT turn red!?
Can anyone advise what I am doing wrong?
Using if (bottomNavigationView.getMenu().findItem(R.id.miHome).isChecked()) condition will be triggered only once, but you need to register a listener to the lifetime of the lifecycle owner of the bottomNavigationView which is the MainActivity.
This is typically the OnNavigationItemSelectedListener
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.miHome) {
fab.setImageResource(R.drawable.ic_add);
} else if (item.getItemId() == R.id.miSettings) {
fab.setImageResource(R.drawable.ic_settings);
fab.setBackgroundColor(Color.RED);
}
return true;
}
});
Related
I have code below:
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(onClickListener);
and XML:
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingStart="0dp"
android:paddingEnd="12dp"
app:contentInsetStart="0dp"
app:navigationIcon="#drawable/ic_menu_black_24dp"
app:title="#string/app_name" />
</com.google.android.material.appbar.AppBarLayout>
I want to call click on navigation icon of toolbar, but i cant find method to do it.
I can't call onClickListener(null) because I change icon inside onClick.
Please try this by replacing 'number' with the index of the icon. (It could be 1-2-3-4 etc.)
toolbar.getChildAt(number).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//do whatever you want here
}
});
Try this,
Toolbar toolbar;
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
You can used setNavigationOnClickListener {} for this.
// I used private function here, you don't need to.
private fun onBackArrowPressed() {
// when user clicked the navigation icon (here is back arrow)
binding.toolbar.setNavigationOnClickListener {
// find the nav controller and pop backstack
findNavController().popBackStack()
}
}
Material Components Android Top AppBar
I want to go from fragment to activity using back button using toolbar back icon.
The fragment is my navigation drawer item & activity is my MainActivity.
How do I do it?
You can use app:navigationIcon="?attr/homeAsUpIndicator" for that back navigation icon.
<android.support.v7.widget.Toolbar
android:id="#+id/toolbarId"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="?attr/homeAsUpIndicator"/>
For navigation:
Toolbar toolbar = (ToolBar) getActivity().findViewById(R.id.toolbarId);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getActivity().onBackPressed();
}
});
Call this method in your fragment onCreateView
public void showBackButton() {
if (getActivity() instanceof ActionBarActivity) {
((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
Try this worked for me :
in XML:
<android.support.v7.widget.Toolbar
android:id="#+id/profileToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
Create an back arrow icon in drawable folder. Name it 'ic_back_button'.
Not sure how :-
just right click on drawable > new > ImageAsset > Clip Art > Search back > select > OK > Finish (don't forget to change the name).
then Inside your fragment in onCreateView :
Toolbar toolbar = view.findViewById(R.id.profileToolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
It might help in case if you want to come back from fragment to previous location.
Put this in your class with navController.
#Override
public boolean onSupportNavigateUp() {
navController.navigateUp();
return super.onSupportNavigateUp();
}
don't forget implement relevant dependency such as navigation and navigation UI.
Add this xml code to your fragment and try
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#FFFFFF"
android:layout_gravity="center"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title Here"
android:typeface="serif"
android:layout_gravity="center"
android:id="#+id/toolbar_title"
android:textSize="20sp"
android:textColor="#android:color/black"/>
<ImageView
android:id="#+id/ivback_water"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:padding="15dp"
android:scaleType="fitCenter"
android:layout_gravity="left"
android:background="#drawable/ic_arrow_back_black_24dp" />
</android.support.v7.widget.Toolbar>
You can easily do that, if you are using a Custom back button that is placed on your Custom top app bar, in the button's onClick() function you can call.. getActivity().onBackPressed();
it would work the same as if you have clicked the android navigation's back button...
I have written a piece of code as part of an app where I want to implement a back button on the action bar/tool bar such that when the button is pressed, the previous page (the page/fragment immediately before the current page/fragment) will be displayed.
This is the code for the ToolBar, DrawerLayout, NavigationView and getSupportActionBar():
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
final NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setVisibility(View.VISIBLE);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
I am unable to use ActionBar. For some reason (I don't know why), my Android studio/ program, will not allow me to use the ActionBar. So I am substituting that with the set/getSupportActionBar().
The function used in relation to this are:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_settings, 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();
switch (id) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
My activity_main.xml file is:
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="#+id/activity_main"
android:orientation="vertical"
tools:openDrawer="start"
tools:context="com.example.albin.settings_menu.SettingsActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Settings"/>
<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">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar">
</FrameLayout>
<android.support.design.widget.NavigationView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:layout_marginTop="-24dp"
app:menu="#menu/options_menu" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
</LinearLayout>
The problem is that I don't know which is the useful code, which is the useless code and how to mix/join/(add additional codes to) these (codes, methods, variables/objects, fragments, xml layouts) to get the desired outcome, that is, the application of a back button on the action bar/tool bar.
Most of the code above is implemented for the up button, not the back button. I have read at several places that up and back buttons are not the same.
I tried several links on internet as well as on this site, but none of them has just what I need.
Hope someone can give me an clear answer...
You can include the back icon in ToolBar:
Initialize ToolBar:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
You can use an drawable icon as a back button.
toolbar.setNavigationIcon(R.drawable.your_drawable_icon);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what do you want here
}
});
If you do not want to use drawable icon then:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what do you want here
}
});
Actually your layout having that issue because you have added toolbar in RelativeLayout so drawer layout is overlapping on it that's why you would not able to click on back arrow, i have fix your layout see below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:navigationIcon="#drawable/ic_back_black"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Settings" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/options_menu" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
The simplest way would be to add parent activity in manifest file as developer docs suggest.
<activity
android:name=".ChildActivity"
android:parentActivityName=".ParentActivity" >
and java code you already have done it, setSupportActionbar and setHomeAsUpEnabled.
Edited :
its necessary to add up action for icon to be visible, as mentioned in
Android Developer Docs
So toolbar gives added flexibility to modify title-bar in Android.
As far as why getActionBar is not working and you are compelled to use getSupportActionBar is because you must be using SupportLibrary. SupportLibrary gives backward compatibility to earlier SDK versions.
If you want to modify your title-bar/header/action-bar extensively
then use toolbar otherwise use action-bar.
Add a navigation click listener to your toolbar , like below
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
If you are referencing some actions from the action bar, such as a Save action or a Share one, and you are overriding onOptionsItemSelected method, then you need to define the behavior when the back or home button is clicked:
#Override public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save:
//save stuff
break;
//this is what you need to add to reference again back/home button
case android.R.id.home:
//do your stuff here, usually back to the home or close the current activity
getActivity().finish();
break;
default:
break;
}
return true;
I have a floating action button in an activity which i plan to display over fragments. The FAB doesnot repond to clicks while the ripple is visible.
I searched SO for similar questions but the answers I found didnot work.
Here is my layout for the FAB.
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:theme="#style/MyTheme">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MainActivityFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/homeFAB"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_gravity="bottom|center"
android:layout_margin="16dp"
android:src="#drawable/ic_add_image"
android:onClick="runThis"
app:layout_anchor="#id/MainActivityFragmentContainer"
app:layout_anchorGravity="bottom|center" />
I rearranged the order of the button in the layout inside the coordinator layout but did not work.
Then I added android:onclick="runThis" to the FAB in the XML and a method in the activity.
public void runThis(View view) {
Toast.makeText(SlidingMenuActivity.this, "CLICKED", Toast.LENGTH_LONG).show();
}
Getting below error:
java.lang.IllegalArgumentException: Expected receiver of type
xxx.xxx.SlidingMenuActivity, but got
android.support.v7.internal.view.ContextThemeWrapper
Please help me figure out what I am missing.
Thank you
You are using fragments you should use click listener instead of defining onClick on xml like this....
inflate fab on onCreate view...
FloatingActionButton myFab = (FloatingActionButton) myView.findViewById(R.id.homeFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doyourThing();
}
});
or
replace SlidingActivity.this with getActivity()
Try with below code and pass instead of SlidingMenuActivity
with getApplicationContext(). It should work.
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
I want to show progress spinner on toolbar while performing background task in UIfragment. I want to use material design for my app, so I set theme with no action bar and used toolbar as action bar. I have tried setProgressBarIndeterminateVisibility(Boolean.TRUE) but its not working.
i solved it by just placing the progress bar inside the toolbar in parent activity layout and then from child fragment accessed the progress bar and showed it when needed
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="3dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/Base.ThemeOverlay.AppCompat.Dark"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light" >
<ProgressBar
android:id="#+id/toolbar_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="#cccccc"
android:indeterminateTintMode="src_in"
android:indeterminate="true"
android:layout_gravity="right"
android:visibility="gone"
/>
</android.support.v7.widget.Toolbar>
If you extends from a ActionBarActivity, try this:
public class MainActivity extends ActionBarActivity {
boolean showUp=true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
setSupportProgressBarIndeterminateVisibility(Boolean.TRUE);
Button b = (Button) findViewById(R.id.myButton);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(showUp){
setSupportProgressBarIndeterminateVisibility(Boolean.FALSE);
}else {
setSupportProgressBarIndeterminateVisibility(Boolean.TRUE);
}
showUp=!showUp;
}
});
}