I use SlidingTabLayout which I grab it from here. There I found a almost a perfect solution for my tab problem. However, I still have some issues with this exapmle. The problem with that example is that it uses the same color for selected tabs and unselected ones. But I want to change the background of the tab when it is selected. I tried to put a selector background to generated tabs on createDefaultTabView(Context context) method in SlidingTabLayout.java
When I do that, indicators are just gone away. I tried to put that selector on onDraw() function in SlidingTabStrip.java but the result was the same.
So, can you tell me a way out?
By the way, I am using a ToolBar. This is why I use SligingTabStrip (as I read, TabHost cannot work with ToolBar). Maybe I am wrong with that as well.
To change the color of selected tab change the selector file like
SlidingTabLayout.java
tabTitleView.setTextColor(getResources().getColorStateList(
R.color.selector));
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#android:color/white"/>
<item android:state_focused="true" android:color="#android:color/blue"/>
<item android:state_pressed="true" android:color="#android:color/green"/>
<item android:color="#ccc"/>
</selector>
Related
I am writing an Android app and now I am styling it. I am using a custom theme which is a child of Theme.Holo.Light. I really like Theme.Holo.Light because its buttons have a special effect when you click and hold it. Like the lower button in the picture below:
Not click:
click:
The upper button has been changed color. Now when I click on that button, it doesn't have that effect. I really don't understand why. Can anyone tell me why this happens and how can I get the same effect with a colored button?
And also, the colored button seems fatter.
This is because the button uses a selector to display different colors/effects/drawables based on the state of the click. You can check out the link on Color State List Resource.
To create your own you have to create a slecetor cml file and put it in your drawables folder.
For example.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/shape_btn_default_normal_gray" android:state_enabled="true" android:state_pressed="false"/>
<item android:drawable="#drawable/shape_btn_default_pressed_gray" android:state_pressed="true"/>
<item android:drawable="#drawable/shape_btn_default_disabled_gray"/>
</selector>
or with colors
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/dark_green" android:state_enabled="true" android:state_pressed="false"/>
<item android:drawable="#color/light_green" android:state_pressed="true"/>
<item android:drawable="#color/gray"/>
</selector>
To apply this you have to set the background drawable in your layout xml like this.
<Button
android:id="#+id/my_btn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Some text"
android:background="#drawable/selector_btn_default_gray"/>
That is the "ripple effect" of material design.You have define you own style for that effect.Link below may help you or you may search for many other answers on StackOverflow. Material effect on button with background color
It does not loses its behavior you can see after click (in your second image) the button show same scale as the above have...so by default the background is set as to show that it is button (like with padding or so) and can changes to show oncklick effect...
So when you set your desire background to button...It takes complete change on what is on presently on it and then you have to manually set onclick effect..
I'm trying so set the text color on sliding tabs within a custom view according to the tab state. It's working but not on initial display.
The textcolor in the custom view should be white when the tab is selected and darker grey otherwise. I got it partly working already: When I select a tab manually the text color changes correctly.
My problem is that on first display the text of the first tab, whose content is displayed initially and before any user interaction with the tabs, is not colored in the active state color (white). Its grey, like the inactive tabs. If I start interacting with the tabs, everything works, but the initial tab color of the first displayed tab is wrong.
[FIRST TAB | SECOND TAB]
^
Grey (inactive color) on first load
EDIT:
The cause seems to be in the styles.xml: If I declare a custom style that inherits from Widget.Design.TabLayout the initial coloring does not work anymore. If I do not declare custom styles for the tablayout, everything works fine!
EDIT2:
No, it doesn't work. It works without setting the custom view but it still does not do the initial coloring correctly when first loading the tabs with setting the custom view.
Here is my code:
tab_gallerylayout.xml (custom tab view)
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mbprojects.retro.view.RetroTextView
android:id="#+id/tab_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#drawable/gallerytab_title_color"
app:font="#string/font_name_syncopate"
/>
</LinearLayout>
gallerytab_title_color.xml (selector)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#android:color/white" />
<item android:state_selected="false" android:color="#android:color/darker_gray" />
<item android:state_focused="true" android:color="#android:color/white" />
<item android:state_pressed="true" android:color="#android:color/white" />
<item android:color="#android:color/darker_grey" />
</selector>
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="#style/Theme.AppCompat.NoActionBar">
</style>
<style name="AppTheme.Base.Widget.Design.TabLayout" parent="Widget.Design.TabLayout">
<item name="tabMaxWidth">#dimen/tab_max_width</item>
<item name="tabIndicatorColor">#android:color/white</item>
<item name="tabIndicatorHeight">0dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">#android:color/black</item>
<item name="tabTextAppearance">#style/TextAppearance.Design.Tab</item>
</style>
Any suggestions?
The reason for this unusual behaviour is that your viewPager sets first item as current internally in viewPager.setAdapter(). This in turn makes tabLayout to select first tab in tabLayout.setupWithViewPager().
After this when you set custom tabs, state of custom view is not changed to "selected" (because select initial tab code already completed before this).
So, you need to explicilty change the state of custom view of selected tab.
Add below line after you set custom tabs and you're good to go.
mTabLayout.getTabAt(mInitialTab).getCustomView().setSelected(true);
You should use android:selector in your xml instead of the android:textColor. The former is for dynamically changing an attribute while the latter is assigning one value and keeping it
I need to add customised Switch to my application. I know that usually to display it in a way you like you need to create a selector for thumb and track resources and set it in the XML, which I did and it works. Code for selectors is as follows:
1. thumb_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/switch_thumb_disabled" android:state_enabled="false"/>
<item android:drawable="#drawable/switch_thumb_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/switch_thumb_activated" android:state_checked="true"/>
<item android:drawable="#drawable/switch_thumb"/>
</selector>
bg_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/switch_bg_disabled" android:state_enabled="false"/>
<item android:drawable="#drawable/switch_bg_focused" android:state_focused="true"/>
<item android:drawable="#drawable/switch_bg_on" android:state_checked="true"/>
<item android:drawable="#drawable/switch_bg"/>
</selector>
These selectors are located in drawable resource folder, so when I use
android:thumb="#drawable/thumb_selector"
android:track="#drawable/bg_selector"
switch is displayed as expected. However, there are other properties and many Views I have to create dynamically, so it is better to add a custom control (which extends Switch), and I need to set ThumbResource and TrackResource. Documentation says there are two methods, which can set it: setThumbResource(int resId) and setTrackResource(int resId), but when I try to reference selector as setThumbResource(R.drawable.thumb_selector) it doesn't recognise this selector as drawable. It's a silly problem and I can't seem to be able to solve it, did I add it to the wrong folder? One way to work around this is to extend layout and inflate xml version of Switch, but do I have to do this? How can I reference selector within the code?
I'm trying to achieve that an icon in ActionBar will not change states discretely, but by fading animation. When I add android:enterFadeDuration and android:exitFadeDuration to the selector tag, my drawable is initially invisible - when I tap it, it changes state to state_pressed (properly with enter fade duration) and when I release it, it turns back to its normal visible unselected state.
I must be missing something obvious, or is this a bug of some kind?
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="150" android:exitFadeDuration="150">
<item android:drawable="#drawable/filters_toggle_icon_selected" android:state_focused="true"/>
<item android:drawable="#drawable/filters_toggle_icon_selected" android:state_pressed="true"/>
<item android:drawable="#drawable/filters_toggle_icon" android:state_focused="false" android:state_pressed="false"/>
</selector>
I had a similar problem, with my code looking like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="#android:integer/config_mediumAnimTime"
android:exitFadeDuration="#android:integer/config_mediumAnimTime" >
<item android:state_pressed="true" android:drawable="#color/pressed" />
<item android:drawable="#color/default" />
</selector>
At first, I found a hint to get rid of enterFadeDuration and only use exitFadeDuration. That solved the problem with initial invisibility, but the view still faded into invisibility during the first interraction.
Then, I modified my structure as follows:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/default" />
<item>
<selector android:enterFadeDuration="#android:integer/config_mediumAnimTime"
android:exitFadeDuration="#android:integer/config_mediumAnimTime" >
<item android:state_pressed="true" android:drawable="#color/pressed" />
</selector>
</item>
</layer-list>
Basically, I just pushed the default drawable out of the selector. It's a workaround and it also works for selectors with multiple states, but has some notable limitations:
The default drawable is always visible as a bottom layer. It works for opaque colors, but transparency may cause undesirable results.
If the view starts in one of the states tested by selector, in still displays as default, because the selector still starts as invisible.
It might not be applicable to the original problem, but it's something to consider for overcoming this behaviour of selectors.
Use android:enterFadeDuration="#android:integer/config_mediumAnimTime" and android:exitFadeDuration="#android:integer/config_mediumAnimTime".
My problem was similar as well, the issue was that after setting a background drawable on my view, it was in the wrong state (sometimes it even mixed the stroke and solid of two states...). This was only before the first interaction, like receiving focus or changing enabled state.
I've found that if you call jumpToCurrentState() on the drawable (which has the fade duration properties) after setting it on the view, it will be set on the correct state, and you can keep on using the enter / exit fade duration properties.
Here's how I did it:
val stateList = (darkBackground as? RippleDrawable)?.findDrawableByLayerId(android.R.id.background) as? StateListDrawable
background = darkBackground
stateList?.jumpToCurrentState()
In this example I had a ripple drawable which contained the selector which had the fade properties (I had to add an ID to the selector so I could look it up using the ID).
This seems to be a bug that happens on specific Android versions. You can turn off the android:enterFadeDuration programmatically in Java code, by accessing the Selector with a StateListDrawable:
// Disable android:enterFadeDuration/exitFadeDuration on Android 4.2 only
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
StateListDrawable stateListDrawable =
(StateListDrawable) animatedButton.getBackground();
stateListDrawable.setEnterFadeDuration(0);
stateListDrawable.setExitFadeDuration(0);
}
I am adding an actionbar to a test app I'm writing, and I see questions throughout stackoverflow about this, but nothing that has helped me at all. Based off of this guide:
http://android-developers.blogspot.com/2011/04/customizing-action-bar.html
I'm trying to change the select color for tabs that i'm using on my action bar. The default is that faint blue color. Just as a test I did this:
<style name="CustomTab" parent="android:style/Widget.Holo.Light.ActionBar.TabView">
<item name="android:background">#000000</item>
</style>
That gives me a solid black tab completely, not the selector part. Can someone help better direct me here? I can't seem to find a good example anywhere.
First you have to define a selector xml file then write this code there and replace your code with this
item name="android:background">#drawable/yourfilename</item>
and the selector xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:state_pressed="true"
android:drawable="#drawable/picture_selected" />
<item
android:state_focused="true"
android:drawable="#drawable/picture_selected" />
<item
android:drawable="#drawable/picture_unselected" />
</selector>