I needed to add bottom navigation bar in my app, which I was able to do very well using the bottombar library that I found in github.
However, another requirement is to change the icons of the bottombar when I click on it. I have not been able to achieve this. Can anyone help me how can I achieve the
My implementation is as follows
bottomBar = BottomBar.attach(view,savedInstanceState);
bottomBar.useDarkTheme(false);
bottomBar.setItemsFromMenu(R.menu.bottom_home_menu, new OnMenuTabSelectedListener() {
#Override
public void onMenuItemSelected(#IdRes int menuItemId) {
switch (menuItemId){
case R.id.menu_home:
Snackbar.make(view,"Home tab",Snackbar.LENGTH_SHORT).show();
break;
case R.id.menu_to_do:
Snackbar.make(view,"To Do tab",Snackbar.LENGTH_SHORT).show();
break;
case R.id.menu_add_books:
Snackbar.make(view,"Add",Snackbar.LENGTH_SHORT).show();
break;
case R.id.menu_notification:
Snackbar.make(view,"Notification",Snackbar.LENGTH_SHORT).show();
break;
case R.id.menu_profile:
Snackbar.make(view,"Profile",Snackbar.LENGTH_SHORT).show();
break;
}
}
});
As per a tutorial that i had seen, it said to add a menu and I did in as shown below. This is the exact code that I have used in the my demo.
Its mentioned in the below snippet.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/menu_home"
android:icon="#drawable/icon_home_hdpi"
android:title="Home"/>
<item
android:id="#+id/menu_to_do"
android:icon="#drawable/icon_todo_hdpi"
android:title="To Do"/>
<item
android:id="#+id/menu_add_books"
android:icon="#drawable/icon_add_hdpi"
android:title="Add"/>
<item
android:id="#+id/menu_notification"
android:icon="#drawable/icon_notification_hdpi"
android:title="Notification"/>
<item
android:id="#+id/menu_profile"
android:icon="#drawable/icon_profile_hdpi"
android:title="Profile"/>
</menu>
I don't have the library to test, but probably you can set for the original icon a StateListDrawable, with different images for different states.
You just need to add this file as drawable and give this xml as Image Background.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/numpad_button_bg_selected" android:state_selected="true"></item>
<item android:drawable="#drawable/numpad_button_bg_pressed" android:state_pressed="true"></item>
<item android:drawable="#drawable/numpad_button_bg_normal"></item>
</selector>
Related
I haven't been able to find quite what I am trying to do on SO, but I feel like it should be such a common interface need that there must be a straightforward way of accomplishing this that I'm missing.
In my style.xml I have two button styles, a standard "active" button and an "inactive" button.
<style name="ButtonStandard">
<item name="android:background">#color/colorGreen</item>
<item name="android:textColor">#android:color/white</item>
<item name="android:padding">#dimen/element_padding</item>
</style>
<style name="ButtonInactive">
<item name="android:background">#color/colorLight</item>
<item name="android:textColor">#android:color/black</item>
<item name="android:padding">#dimen/element_padding</item>
</style>
I am setting one button to ButtonStandard and the other to ButtonInactive. When I click the inactive button, I want to change it to use the ButtonStandard type and vice versa. I don't want to programmatically set the styles individually in case I decide to later change the button styles and it would be unreliable to have to change it in every location.
activeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activeButton.[somehowsetstyle](R.style.ButtonInactive);
inactiveButton.[somehowsetstyle](R.style.ButtonStandard);
}
});
How can I change between these styles when users click on buttons? The most important is to not have to set specific styles within the code which is just a last resort imho.
Thanks!
Solution Notes
Generally I followed the solution below but instead I created the selector as a drawable and used android:drawable instead because it seems the button background needs that, even if just specifying a color. I also used state_activated rather than enabled so that it is only changing the look of the button and doesn't prevent clicks.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="false"
android:drawable="#color/colorPrimaryDark" />
<item android:state_activated="true"
android:drawable="#color/colorGreen" />
<item android:drawable="#color/colorGreen" />
In XML
android:background="#drawable/selector_btn_bkg"
android:state_activated="false"
In Java
myButton.setActivated(true);
What you are looking for is ColorStateList
drawable/my_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:color="#color/enabled_color"/>
<item android:color="#color/enabled_color"
android:state_enabled = "true"/>
<item android:color="#color/disbaled_color"
android:state_enabled = "false"/>
</selector>
my_view.xml
...
<Button
android:id="#+id/my_button"
android:enabled="false"
android:background="#drawable/my_selector"/>
Java code
onClick(View v){
myButton.setEnabled(true);
}
I have added BottomNavigationView in my application like.
main.xml
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/bottom_navigation_main" />
bottom_navigation_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorites"
android:enabled="true"
android:icon="#drawable/ic_favorite_white_24dp"
android:title="#string/text_favorites"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_schedules"
android:enabled="true"
android:icon="#drawable/ic_access_time_white_24dp"
android:title="#string/text_schedules"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_music"
android:enabled="true"
android:icon="#drawable/ic_audiotrack_white_24dp"
android:title="#string/text_music"
app:showAsAction="ifRoom" />
</menu>
MainActivity click
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorites:
//need change icon of favotites here.
case R.id.action_schedules:
case R.id.action_music:
}
return true;
}
});
I want to change the icon of the bottom navigation of selected position. How can we achieve this feature when user click one item?
(if user clicked one item then the icon change to another one)
You can simply create drawable selector in drawable folder and image can be change according to the state of the widget used in view
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/calender_green" android:state_checked="true"/>
<item android:drawable="#drawable/calender_black" android:state_checked="false"/>
</selector>
I found this is better approach to use selector drawable:
At first create an xml file in your drawable folder.
For example, xml file name is child_selector.xml at drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/child" android:state_checked="false"/>
<item android:drawable="#drawable/child_fill" android:state_checked="true"/>
</selector>
Simply add child_selector in menu item of your bottom_navigation_main.xml:
Like: android:icon="#drawable/child_selector"
Example:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_child"
android:icon="#drawable/child_selector"
android:title="#string/title_child" />
</menu>
And must add following line in your activity-
bottomNavigationView.setItemIconTintList(null);
If above solutions are not working for you to change selected item icon then add below line to your code:
bottomNavigationView.setItemIconTintList(null);
This will disable tint effect of selected item icon.
I had the same problem. I have added selector drawable for changing icon of BottomNavigationView item when its checked/selected.
You need to reset the icon onclick, and then on the switch case you need to set only the one you need to change, so only when selected the icon change.
Menu menu = bottomNavigationView.getMenu();
menu.findItem(R.id.action_favorites).setIcon(favDrawable);
switch (item.getItemId()) {
case R.id.action_favorites:
item.setIcon(favDrawableSelected);
case R.id.action_schedules:
case R.id.action_music:
}
Okay I wanted to understand how to have each item have their own image, and with some confusion in the comments on where it should go, I wanted to type up this answer.
First create your menu and its items. Your selector will go inside those items in the ICON value. Here we have 2 selectors, each made for its menu item.
item
android:id="#+id/navigation_home"
android:icon="#drawable/navigation_home_selector"
android:title="#string/title_home" />
item
android:id="#+id/navigation_profile"
android:icon="#drawable/navigation_profile_selector"
android:title="#string/title_profile" />
Now here is your selector file that will be housed in your drawable folder.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/menu_selected" android:state_checked="true"/>
<item android:drawable="#drawable/menu" android:state_checked="false"/>
</selector>
Final step was provided by #
KishanSolanki124
Add this line of code to your BottomNavigationView.
BottomNavigationView.setItemIconTintList(null);
There you have it. All works like a charm.
The above answer from ajay singh https://stackoverflow.com/a/57248961/9793057 helped me out, as well as employing answers from above.
The following code within res->drawable folder (selector_stock_bottom_nav_view.xml)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/button_and_tab_color" android:state_checked="true" />
<item android:color="#android:color/darker_gray" android:state_checked="false" />
</selector>
These are the attributes in my bottom navigation view
<com.google.android.material.bottomnavigation.BottomNavigationView
app:itemIconTint="#drawable/selector_stock_bottom_nav_view" //To change icon color
app:itemTextColor="#drawable/selector_stock_bottom_nav_view" //To change text color
app:itemTextAppearanceActive="#style/stockBottomNavigationView.Active" //To change size of text during active state
app:itemTextAppearanceInactive="#style/stockBottomNavigationView.InActive"
app:menu="#menu/bottom_navigation_menu"
app:labelVisibilityMode="labeled"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:selectedBackgroundVisible="false"
android:id="#+id/stock_bottom_navigation"/>
I DID-NOT use "BottomNavigationView.setItemIconTintList(null)" anywhere in my code.
Now here comes the most important piece of code, make sure to return "TRUE" in bottom navigation view's listener, i.e,
private BottomNavigationView.OnNavigationItemSelectedListener stockBottomNavListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
return true;
}
};
Bonus: To change size of text active/inactive state
Place the following code in styles.xml file
<style name="stockBottomNavigationView.InActive" parent="#style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">7sp</item>
</style>
<style name="stockBottomNavigationView.Active" parent="#style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">8sp</item>
</style>
The above answer is a compilation of answers from various answers in stackoverflow related to bottom navigation views, icon & text color/size change.
Thanks for the selector method, that works for me (api v26)
For those who wondering how to set it back to origin unselected icon programmatically, consider add this to your OnNavigationItemSelectedListener before your switch(Java) or when(Kotlin) :
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
navigation.menu.getItem(0).setIcon(R.drawable.ic_tab_home)
navigation.menu.getItem(1).setIcon(R.drawable.ic_tab_account)
navigation.menu.getItem(2).setIcon(R.drawable.ic_tab_trading)
navigation.menu.getItem(3).setIcon(R.drawable.ic_tab_wallet)
when (item.itemId) {
R.id.navigation_home -> {
message.setText(R.string.title_home)
item.setIcon(R.drawable.ic_tab_home_active)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_account -> {
message.setText(R.string.title_account)
item.setIcon(R.drawable.ic_tab_account_active)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_trading -> {
message.setText(R.string.title_trading)
item.setIcon(R.drawable.ic_tab_trading_active)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_wallet-> {
message.setText(R.string.title_wallet)
item.setIcon(R.drawable.ic_tab_wallet_active)
return#OnNavigationItemSelectedListener true
}
}
false
}
Found the answer. we can use
item.setIcon(R.drawable.icon_name)
to change the icon .. will try to imporve answer
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorites:
//change the icon
item.setIcon(R.drawable.icon_name);
case R.id.action_schedules:
case R.id.action_music:
}
return true;
}
});
You can dynamically set your icon using this method.
R.id.navigation_menu is your item id in your R.menu.menu_bottom_navigation.
val menuItem = bottomNavigationView.menu.findItem(R.id.navigation_menu)
menuItem.setIcon(R.drawable.ic_icon)
On Material 3
You need to create a style and put your colors on:
<style name="BottomNavigationView">
<item name="colorSecondaryContainer">#color/background_dark</item>
<item name="colorSurface">?attr/colorPrimaryVariant</item>
<!-- Icon color Active -->
<item name="colorOnSecondaryContainer">#color/yellow</item>
<!-- Text Color Active -->
<item name="colorOnSurface">#color/yellow</item>
</style>
To see inactive colors, check the documentation.
In the Latest material Design library default behavior of BottomNavigation is provided where you don't need to provide property itemIconTint it will manage it automatically.
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:itemBackground="#color/white"
app:itemTextColor="#color/textBlue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_navigation"
app:labelVisibilityMode="labeled"
app:itemTextAppearanceActive="#color/colorPrimary"
/>
i'm try to apply actionbar in my android, i copied a menu xml from another app to current app (/res/layout/menu/actionbarmenu.xml)
here is the code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/media_play"
android:icon="#android:drawable/ic_media_play"
android:title="#string/media_play"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_pause"
android:icon="#android:drawable/ic_media_pause"
android:title="#string/media_pause"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_previous"
android:icon="#android:drawable/ic_media_previous"
android:title="#string/media_previous"
android:showAsAction="ifRoom" />
<item android:id="#+id/media_next"
android:icon="#android:drawable/ic_media_next"
android:title="#string/media_next"
android:showAsAction="ifRoom">
</item>
</menu>
In every line "ifRoom|withText", there is a red underline appear and with yellow box :
Should use app:showAsAction with the appcompat library with
xmlns:app="http://schemas.android.com/apk/res/auto"
Anyone know what is the problem?
You should use app namespace for menu which is part of appcompat.
<?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/media_play"
android:icon="#android:drawable/ic_media_play"
android:title="#string/media_play"
app:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_pause"
android:icon="#android:drawable/ic_media_pause"
android:title="#string/media_pause"
app:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_previous"
android:icon="#android:drawable/ic_media_previous"
android:title="#string/media_previous"
app:showAsAction="ifRoom" />
<item android:id="#+id/media_next"
android:icon="#android:drawable/ic_media_next"
android:title="#string/media_next"
app:showAsAction="ifRoom">
</item> </menu>
The android:showAsAction has been added in API 11 and your app has probably lower minimum API level. You can use the AppCompat library which will provide this parameter and its desired behavior, however, to reffer the AppCompat parameter you have to call it within the right XML namespace.
The namespace is included by the suggested code added to root <menu> tag
xmlns:app="http://schemas.android.com/apk/res/auto"
and then you can add app:showAsAction to your <item> tags
When you press on a button in Android it changes color. I want it to stay like that. I mean i want something like this:
Button btn = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
btn.setBackGroundColor(R.drawable.clicked /*clicked style*/ );
}
});
example:
This is a pressed on button. I want it to stay like that after i stop pressing it. Is there a easy way like that:
android.R.drawable.btn_default //this is the default button style, i want the pressed one :D
In your java code write button.setPressed(true);.It will set button in pressed mode. You can change the parameter to true and false when you want to set it pressed and unpressed...
Try using selector:
Define selector.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_pressed_yellow"
android:state_pressed="true" />
<item android:drawable="#drawable/button_normal_green" />
</selector>
and set background of the button to android:background="#drawable/selector" then in the code on the click event of the button set btn.setpressed(true);
So you want it to start non-pressed and then stay pressed after being clicked one?
Try using an OnTouchListener instead adding btn.setPressed(true);:
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
btn.setPressed(true);
}
return true;
}
Take a look of the StateSelector images
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
You can set diferent resources for the diferent states of your button/view. This example set different colors:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/branded_content_pressed_color" android:state_enabled="true" android:state_pressed="true"/>
<item android:drawable="#color/branded_content_pressed_color" android:state_enabled="true" android:state_focused="true"/>
<item android:drawable="#color/branded_content_background_color"/>
</selector>
Then you can set the selector normally
button.setBackgroundResource(R.drawable.selector);
You can try this way either put image as dark when press or color
drawable/selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:drawable="#drawable/buttondark"/>
<item android:state_pressed="true" android:drawable="#drawable/buttondark" />
<item android:drawable="#drawable/button" />
</selector>
inside on-create method write
btn.setBackgroundResource(R.drawable.selector);
I'm using ActionBarSherlock. I have a MenuItem, and I want to use a custom selector with only that MenuItem, not the others in the ActionBar. This is the menu code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_include_location"
android:icon="#drawable/icon_place_selector"
android:showAsAction="always"
android:title="#string/menu_include_location"/>
<item
android:id="#+id/menu_send"
android:icon="#drawable/ic_send"
android:showAsAction="ifRoom|withText"
android:title="#string/menu_send"/>
</menu>
Here is the icon_place_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/location_place" android:state_pressed="false"/>
<item android:drawable="#drawable/location_no_gradient" android:state_pressed="true"/>
</selector>
The issue is that in the MenuItem, the icon is only a small part of it. Here's a screenshot of what shows up. The entire background should change, and not just the icon. How do I do that?
You can change the selector of a particular action bar item by setting a custom ActionView in the code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.activity_main, menu);
MenuItem menuItem = menu.findItem(R.id.menu_include_location);
ImageView image = new ImageView(this);
image.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
image.setPadding(16, 0, 16, 0);
image.setImageResource(R.drawable.ic_launcher);
image.setBackgroundResource(R.drawable.icon_place_selector);
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// ...
}
});
menuItem.setActionView(image);
return true;
}
Apply these styles if you want to change the selector for all action bar items:
<style name="AppTheme" parent="#style/Theme.Sherlock">
<item name="android:selectableItemBackground">#drawable/icon_place_selector</item>
<item name="android:actionBarItemBackground">#drawable/icon_place_selector</item>
</style>
Use Actionbar style generator, to style your style and download zip file
In downloaded zip file open selectable_background_xxxx.xml (xxxx -> name given to your own style) file in "drawables" folder and change the drawable to nine-patch img or color code you want when pressed state is true.
<item android:state_pressed="true" android:drawable="#color/your_color" />
first you shall know, if you set android:selectableItemBackground in your holo style, the whole widget, i.e. a button, will have that background selector.
if you just need to change your actionbar menuitem' s icon selector background, Here is a simple answer!
just set android:actionBarItemBackground in your holo style!
<style name="AppTheme.Dark" parent="android:Theme.Holo">
<item name="android:actionBarItemBackground">#drawable/item_background_holo_light</item>
</style>
hope it helpful:-)