Design BottomNavigationView - set background color in code - android

Is there any way to set the background color of the new design libraries BottomNavigationView in code to a custom color value instead of a color resource? Any "trick" maybe?
My current solution:
I make the BottomNavigationView transparent
I add a second view behind the bottomNavigationView
I update this view's background
But this looks ugly, especially as I have to use a custom behaviour for the background view to be animated in parallel with the BottomNavigationView in the parent CoordinatorLayout...

Solved it myself.
Solution 1
I just setup all items with a transparent background (this needs one resource file only) and then I theme the BottomNavigationView actual background itself.
bottomBar.setBackground(new ColorDrawable(color));
bottomBar.setItemBackgroundResource(R.drawable.transparent);
Resource drawable - transparent.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#android:color/transparent" />
</shape>
Solution 2 - via reflection (support library 25.0.0)
public void themeBottomBarBackgroundWithReflection(BottomNavigationView bottomBar, int color)
{
try
{
Field mMenuViewField = BottomNavigationView.class.getDeclaredField("mMenuView");
mMenuViewField.setAccessible(true);
BottomNavigationMenuView mMenuView = (BottomNavigationMenuView)mMenuViewField.get(bottomBar);
Field mButtonsField = BottomNavigationMenuView.class.getDeclaredField("mButtons");
mButtonsField.setAccessible(true);
BottomNavigationItemView[] mButtons = (BottomNavigationItemView[])mButtonsField.get(mMenuView);
for (BottomNavigationItemView item : mButtons) {
ViewCompat.setBackground(item, new ColorDrawable(color));
}
}
catch (NoSuchFieldException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}

After many search, only this resolve my case:
bottomNavigationView.setItemBackground(new ColorDrawable(color));
Here I set each one of background item.

Related

Android Kotlin - Changing the background of a button programmatically

How can I change the background of a button programmatically with Android using Kotlin?
This is the way to change background programmatically :
button.backgroundTintList = ContextCompat.getColorStateList(this, R.color.yourColor)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
/// write your custome code here...
</shape>
create drawable in /app/src/main/res/drawable/btn_drawable.xml
and set it as background of button.
button.setBackgroundResource(R.drawable.btn_drawable);
Change background on button click :
button.setOnClickListener {
if(isThemeOne){
button.setBackgroundResource(R.drawable.btn_drawable_1);
isThemeOne=false;
} else {
button.setBackgroundResource(R.drawable.btn_drawable_2);
isThemeOne=true;
}
}
try this easy way for all version
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
btn.setBackgroundColor(getColor(R.color.black))
}else{
btn.setBackgroundColor(resources.getColor(R.color.black))
}

I want to Change the backgroud Colo of Specific Recycler VIew Item

I want to change the Background Color Green OF the Recycler View data Whose Status IS Ture and Set Backround Color RED whose status is False.
The Round One Status is True and rest are False.
So can any one tell me how i Differentiate ...
My Recycler View code Write Below.
#Override
public void onBindViewHolder(DocRecycleAdoptor.MyViewHolder holder, int position) {
final EmpAttandance empAttandance = mDocs.get(position);
holder.txtDocID.setText(empAttandance.getDOC_ID());
holder.txtEmpID.setText(empAttandance.getEMP_ID());
holder.dateTime.setText(empAttandance.getDATE()+" "+empAttandance.getTIME());
holder.txtCoID.setText(empAttandance.getCO_ID());
holder.txtStatus.setText(empAttandance.getSA());
holder.empName.setText(empAttandance.getEmpName());
if(empAttandance.getStatus() == "True"){
holder.itemView.setBackgroundColor(Color.GREEN);
}else{
holder.itemView.setBackgroundColor(Color.RED);
}
}
Now it Shows like This.
But I want When Status is False Color Will Red.
it didit hapen.
top three Status are True And Other is false.
Showing all in same color
In your onBindViewHolder add below check
if(empAttandance.getStatus()){
//set your desired color on textview or a view for status true
}else{
//set your desired color on textview or a view for status false
}
#Override public void onBindViewHolder(DocRecycleAdoptor.MyViewHolder holder, int position) {
final EmpAttandance empAttandance = mDocs.get(position);
holder.txtDocID.setText(empAttandance.getDOC_ID());
holder.txtEmpID.setText(empAttandance.getEMP_ID());
holder.dateTime.setText(empAttandance.getDATE()+" "+empAttandance.getTIME());
holder.txtCoID.setText(empAttandance.getCO_ID());
holder.txtStatus.setText(empAttandance.getSA());
holder.empName.setText(empAttandance.getEmpName());
// this is it
holder.rootLayout.setBackgroundColor(empAttandance.getStatus() ? GREEN : RED);
}
inside your activity_docattd_list_items add linear layout.
add inside linearlayout a drawable #drawarble/selector_gray_view.
#selector_gray_view.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/gradient_gray_light"
android:state_pressed="true"/>
<item android:drawable="#color/clicked"
android:state_focused="true"/>
</selector>
and after that add drawble #gradient_gray_light.
#gradient_gray_light.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#30888888"
android:endColor="#30888888"
android:angle="90" />
</shape>`enter code here`
and after that add another drawable ,
click inside your selector_gray_view.xml,
#drawable/color.
and also intialize linearlayout in myviewholder.
use it inside onbindviewholder like as:
holder.linearlayout.setonclicklistener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
);
happy coding.
In ANdroid == are Not working. so i use empAttandance.getStatus().equal("True") instead Of == and its working Fine.
Thanks to All of you Guys for helping me out. much appreciate.
if(empAttandance.getStatus().equal("True")){
//set your desired color on textview or a view for status true
}else{
//set your desired color on textview or a view for status false
}

How to get color of a button with ripple drawable

I have variety of buttons and I would like to get their background color, getting background color in a color drawable is easy but it is not easy in ripple drawable, how can I manage to get background color from ripple drawable.
Try this:
RippleDrawable rippleDrawable = (RippleDrawable) button.getBackground();
Drawable.ConstantState state = rippleDrawable.getConstantState();
try {
Field colorField = state.getClass().getDeclaredField("mColor");
colorField.setAccessible(true);
ColorStateList colorStateList = (ColorStateList) colorField.get(state);
int rippleColor = colorStateList.getDefaultColor();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
The solution that I found was to remove entries from the manifest of a newly minted app - particularly look at styles, themes and colours - compare older working apps with the new one to determine suspects.
The RippleDrawable then replaced itself with the ColorDrawable that it had been and .getColor() works again.
please check following example for ripple effect in android..
http://www.viralandroid.com/2015/09/how-to-add-ripple-effect-to-android-button.html

Change TapDown Color on ListView

I have a list view and when the user taps down on the item it looks like this.
This is what it looks like noramally:
How do I change this default light blue color?
I need the color to be set programatically in the activity file, as it is not always the same color, and also how do you change the color of the fuzzy stuff that comes up at the bottom of a ListView when you continue to scroll down?
Thanks for the help
EDIT
Also how do you change the tap down color of the action bar back button,
For the row color, you need to create a StateListDrawable and set it as the selector for the ListView.
The states to include should be, at least:
pressed (android.R.attr.state_pressed)
selected (android.R.attr.state_selected)
"normal" (empty state list)
For each state you can set any drawable. If what you need is a plain color, you can programmatically create a ColorDrawable on the spot.
For example:
StateListDrawable selector = new StateListDrawable();
ColorDrawable red = new ColorDrawable(Color.RED);
ColorDrawable transparent = new ColorDrawable(Color.TRANSPARENT);
selector.addState(new int[] { android.R.attr.state_pressed }, red);
selector.addState(new int[] { android.R.attr.state_selected }, red);
selector.addState(new int[] { }, transparent);
listView.setSelector(selector);
As for the "fuzzy stuff that comes up at the bottom", it's slightly more complicated.
Prior to Android 5.0 there was no public API for changing it.
In Lollipop it can be set via the theme, but not programmatically.
For pre-5.0 there is a well-known workaround (described here) which involves tampering with the drawables that are used. However this solution crashes in 5.0, because those resources do not exist anymore.
For Android 5.0, if a static color is acceptable, you can just configure the new theme attribute android:colorEdgeEffect (which is the same as android:colorPrimary by default).
If a programmatic solution for Android 5.0 is necessary, you could alternatively change the EdgeEffect objects that the ListView has internally using reflection. I've tested this and it works, though it's not the prettiest code:
EdgeEffect edgeEffectTop = new EdgeEffect(this);
edgeEffectTop.setColor(Color.RED);
EdgeEffect edgeEffectBottom = new EdgeEffect(this);
edgeEffectBottom.setColor(Color.RED);
try {
Field f1 = AbsListView.class.getDeclaredField("mEdgeGlowTop");
f1.setAccessible(true);
f1.set(listView, edgeEffectTop);
Field f2 = AbsListView.class.getDeclaredField("mEdgeGlowBottom");
f2.setAccessible(true);
f2.set(listView, edgeEffectBottom);
} catch (Exception e) {
e.printStackTrace();
}
Therefore, a full programmatic solution may run something like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
// For Android >= 5.0, use setColor() on EdgeEffect
EdgeEffect edgeEffectTop = new EdgeEffect(this);
edgeEffectTop.setColor(Color.RED);
EdgeEffect edgeEffectBottom = new EdgeEffect(this);
edgeEffectBottom.setColor(Color.RED);
try {
Field f1 = AbsListView.class.getDeclaredField("mEdgeGlowTop");
f1.setAccessible(true);
f1.set(listView, edgeEffectTop);
Field f2 = AbsListView.class.getDeclaredField("mEdgeGlowBottom");
f2.setAccessible(true);
f2.set(listView, edgeEffectBottom);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
// For Android < 5.0, change overscroll_glow and overscroll_edge
int glowDrawableId = getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
int edgeDrawableId = getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
}
How do I change this default light blue color?
you have to create StateListDrawable and set it as the selector for the ListView. the answer of matiash is good and I do not want to explain it again.
change the color of the fuzzy stuff that comes up at the bottom of a
ListView when you continue to scroll down
setCacheColorHint (int color)
Also how do you change the tap down color of the action bar back
button
<style name="actionbarCustomBackground" parent="#style/Theme.Holo.Light" >
<item name="android:selectableItemBackground">#drawable/actionbar_item_background</item>
</style>
then in the actionbar_item_background:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item
android:state_focused="true"
android:state_pressed="true"
android:drawable="#android:color/holo_orange_dark" />
<item
android:state_pressed="true"
android:drawable="#android:color/holo_orange_dark" />
<item
android:drawable="#android:color/transparent" />
</selector>
You can set row's background dynamically in getView(..) method.
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
.......... //your code
view.setBackgroundColor(Color.RED)
return view;
}

Honeycomb - customize SearchView inside the action bar

I have a field where the user can type a search query in the action bar of the application. This is declared in the action bar using a menu inflate in the Activity:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:id="#+id/action_search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"
android:title="#string/search"
></item>
</menu>
I need to customize the appearance of the SearchView (for instance background and text color). So far I could not find a way to do it using XML (using styles or themes).
Is my only option to do it in the code when inflating the menu?
Edit #1: I have tried programmatically but I cannot get a simple way to set the text color. Plus when I do searchView.setBackgroundResource(...) The background is set on the global widget, (also when the SearchView is iconified).
Edit #2: Not much information on the Search Developer Reference either
Seibelj had an answer that is good if you want to change the icons. But you'll need to
do it for every API version. I was using ICS with ActionBarSherlock and it didn't do justice for me but it did push me in the correct direction.
Below I change the text color and hint color. I showed how you might go about changing the
icons too, though I have no interest in that for now (and you probably want to use the default icons anyways to be consistent)
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Set up the search menu
SearchView searchView = (SearchView)menu.findItem(R.id.action_search).getActionView();
traverseView(searchView, 0);
return true;
}
private void traverseView(View view, int index) {
if (view instanceof SearchView) {
SearchView v = (SearchView) view;
for(int i = 0; i < v.getChildCount(); i++) {
traverseView(v.getChildAt(i), i);
}
} else if (view instanceof LinearLayout) {
LinearLayout ll = (LinearLayout) view;
for(int i = 0; i < ll.getChildCount(); i++) {
traverseView(ll.getChildAt(i), i);
}
} else if (view instanceof EditText) {
((EditText) view).setTextColor(Color.WHITE);
((EditText) view).setHintTextColor(R.color.blue_trans);
} else if (view instanceof TextView) {
((TextView) view).setTextColor(Color.WHITE);
} else if (view instanceof ImageView) {
// TODO dissect images and replace with custom images
} else {
Log.v("View Scout", "Undefined view type here...");
}
}
adding my take on things which is probably a little more efficient and safe across different android versions.
you can actually get a numeric ID value from a string ID name. using android's hierarchyviewer tool, you can actually find the string IDs of the things you are interested in, and then just use findViewById(...) to look them up.
the code below sets the hint and text color for the edit field itself. you could apply the same pattern for other aspects that you wish to style.
private static synchronized int getSearchSrcTextId(View view) {
if (searchSrcTextId == -1) {
searchSrcTextId = getId(view, "android:id/search_src_text");
}
return searchSrcTextId;
}
private static int getId(View view, String name) {
return view.getContext().getResources().getIdentifier(name, null, null);
}
#TargetApi(11)
private void style(View view) {
ImageView iv;
AutoCompleteTextView actv = (AutoCompleteTextView) view.findViewById(getSearchSrcTextId(view));
if (actv != null) {
actv.setHint(getDecoratedHint(actv,
searchView.getContext().getResources().getString(R.string.titleApplicationSearchHint),
R.drawable.ic_ab_search));
actv.setTextColor(view.getContext().getResources().getColor(R.color.ab_text));
actv.setHintTextColor(view.getContext().getResources().getColor(R.color.hint_text));
}
}
You can use the attribute android:actionLayout instead which lets you specify a layout to be inflated. Just have a layout with your SearchView and you won't have to modify anything really.
As to changing text style on the SearchView that is probably not possible as the SearchView is a ViewGroup. You should probably try changing text color via themes instead.
In case anyone wants to modify the views directly, here is how you can change the colors/fonts/images and customize the search box to your pleasure. It is wrapped in a try/catch in case there are differences between versions or distributions, so it won't crash the app if this fails.
// SearchView structure as we currently understand it:
// 0 => linearlayout
// 0 => textview (not sure what this does)
// 1 => image view (the search icon before it's pressed)
// 2 => linearlayout
// 0 => linearlayout
// 0 => ImageView (Search icon on the left of the search box)
// 1 => SearchView$SearchAutoComplete (Object that controls the text, subclass of TextView)
// 2 => ImageView (Cancel icon to the right of the text entry)
// 1 => linearlayout
// 0 => ImageView ('Go' icon to the right of cancel)
// 1 => ImageView (not sure what this does)
try {
LinearLayout ll = (LinearLayout) searchView.getChildAt(0);
LinearLayout ll2 = (LinearLayout) ll.getChildAt(2);
LinearLayout ll3 = (LinearLayout) ll2.getChildAt(0);
LinearLayout ll4 = (LinearLayout) ll2.getChildAt(1);
TextView search_text = (TextView) ll3.getChildAt(1);
search_text.setTextColor(R.color.search_text);
ImageView cancel_icon = (ImageView)ll3.getChildAt(2);
ImageView accept_icon = (ImageView)ll4.getChildAt(0);
cancel_icon.setBackgroundDrawable(d);
accept_icon.setBackgroundDrawable(d);
} catch (Throwable e) {
Log.e("SearchBoxConstructor", "Unable to set the custom look of the search box");
}
This example shows changing the text color and the background colors of the cancel/accept images. searchView is a SearchView object already instantiated with it's background color:
Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
searchView.setBackgroundDrawable(d);
Here is the drawable code:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/white" />
</shape>
Obviously, this is hacky, but it will work for now.
From ICS this is doable using themes and styles. I'm using ActionBarSherlock which makes it applicable also for HC and below.
Add a style to define "android:textColorHint":
<style name="Theme.MyHolo.widget" parent="#style/Theme.Holo">
<item name="android:textColorHint">#color/text_hint_corp_dark</item>
</style>
Apply this as "actionBarWidgetTheme" to your theme:
<style name="Theme.MyApp" parent="#style/Theme.Holo.Light.DarkActionBar">
...
<item name="android:actionBarWidgetTheme">#style/Theme.MyHolo.widget</item>
</style>
Presto! Make sure that you use getSupportActionBar().getThemedContext() (or getSupportActionBar() for ActionBarSherlock) if any widgets are initiated where you might have other themes in effect.
How do you inflate the menu xml in your Activity? if you inflate the menu by using getMenuInflator() in your Activity, then the menu and also the searchView get the themed context, that have attached to the activity.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater.inflate(R.menu.search_action_menu, menu);
}
if you check the source code of Activity.getMenuInflator() at API-15, you can see the themed context codes. Here it is.
*/
public MenuInflater getMenuInflater() {
// Make sure that action views can get an appropriate theme.
if (mMenuInflater == null) {
initActionBar();
if (mActionBar != null) {
mMenuInflater = new MenuInflater(mActionBar.getThemedContext());
} else {
mMenuInflater = new MenuInflater(this);
}
}
return mMenuInflater;
}

Categories

Resources