Dynamic Spinner with icons inheriting AppCompat theme - android

I am trying to achieve two things:
Make my Spinners inherit from the AppCompat themes.
Add icons to the spinner elements, as is possible in the Toolbar popup menus.
Since I am not able to achieve the first point I am focusing on that, but I also want to add icons later on. As it is now, my Toolbar popup menus inherit the AppCompat theme, but the Spinners do not, as shown in the pictures below. The first image shows the (proper) popup menu from the Toolbar, while the second shows the popup menu from a Spinner. This is an example of a Spinner that is not inheriting the style. Or should this popup menu style be expected?
I have tried loads of things, so there are likely multiple duplicates of this question, but I am not able to make it work. What can be wrong in the code below? After the theme is inherited correctly, how can I add icons later on? Minimum SDK version is 16, target is 23.
themes.xml:
<resources>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimary">#color/my_brown</item>
<item name="colorPrimaryDark">#color/my_dark_gray</item>
<item name="colorAccent">#color/my_green</item>
<!-- This is just a test, it makes no difference. -->
<item name="android:spinnerStyle">#style/MySpinnerStyle</item>
</style>
<style name="MyTheme" parent="MyTheme.Base"></style>
<!--
ActionBar style, applied directly to XML elements
-->
<style name="MyActionBarStyle" parent="#style/Widget.AppCompat.ActionBar">
<item name="theme">#style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="popupTheme">#style/ThemeOverlay.AppCompat.Light</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#color/my_brown</item>
<item name="android:minHeight">?attr/actionBarSize</item>
</style>
<!--
Spinner style, for testing. Also tried applied directly to xml Spinners.
-->
<style name="MySpinnerStyle" parent="#style/Widget.AppCompat.Spinner">
<item name="popupTheme">#style/ThemeOverlay.AppCompat.Light</item>
<item name="android:popupMenuStyle">#style/Widget.AppCompat.Light.PopupMenu</item>
</style>
</resources>
The Spinner is set up as simply as:
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, mCategories);
mSpinner.setAdapter(adapter);
where mSpinner is the inflated Spinner and mCategories is a String array. In XML the Spinner is defined as
<Spinner
android:id="#+id/my_spinner"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
I have tried adding various styles directly to the Spinner, but it does not work.
In my AndroidManifest.xml I have added the following to the Application tag:
android:theme="#style/MyTheme"

I managed to do it (or to be very close to it) by changing themes and styles like that:
Just add to your theme:
<item name="android:spinnerDropDownItemStyle">#style/MySpinnerItem</item>
Then create a style for MySpinnerItem that inherits from Widget.AppCompat.DropDownItem.Spinner:
<style name="MySpinnerItem" parent="#style/Widget.AppCompat.DropDownItem.Spinner">
<item name="android:textColor">#color/your_text_color</item>
<item name="android:textSize">16sp</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingStart" tools:targetApi="jelly_bean_mr1">16dp</item>
<item name="android:paddingRight">16dp</item>
<item name="android:paddingEnd" tools:targetApi="jelly_bean_mr1">16dp</item>
</style>
That's it for the AppCompat theme.
Finally, if you want to add icons to list items, you have to create a custom layout and set it programmatically. You can follow this tutorial http://android-er.blogspot.sg/2010/12/custom-arrayadapter-for-spinner-with.html that explains it.
Basically you have to:
create a custom layout
create a custom adapter that inherits from ArrayAdapter
implements getCutomView() methods to set your different images for each item
finally set your adapter to the spinner with MyCustomAdapter.createFromResource(this, R.array.my_data, R.layout.my_cutom_item_layout);

The cause of my problem was in the line
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, mCategories);
Here I am using android.R.layout.simple_spinner_item which is probably meant for the Spinner itself. Using android.R.layout.simple_spinner_dropdown_item instead gives the desired look for the dropdown items.
The difference between those are described in some detail in this question, though the images are for older Android versions.
For reference, here are the two layouts taken directly from the Android source code.
simple_spinner_item
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textAlignment="inherit"/>
simple_spinner_dropdown_item
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?android:attr/dropdownListPreferredItemHeight"
android:ellipsize="marquee"/>
Adding icons to the dropdown items
Now, for the icon part, I followed the steps from #euitam and ended up with the following:
MyAdapter:
public class MyAdapter extends ArrayAdapter<String>
{
private String[] mCategories;
private int[] mIcons;
public CategoryDropDownAdapter(Context context, int layoutResourceId, String[] categories)
{
super(context, layoutResourceId, categories);
mCategories = categories;
// Add the same icon to all items, just for testing.
mIcons = new int[mCategories.length];
for (int i = 0; i < mIcons.length; i++)
{
mIcons[i] = R.drawable.my_icon;
}
}
/**
* View for a dropdown item.
* */
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View rowView = convertView;
if (rowView == null)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
rowView = inflater.inflate(R.layout.my_spinner_categories_dropdown_item, parent, false);
}
TextView categoryText = (TextView) rowView.findViewById(R.id.my_spinner_dropdown_item_text);
categoryText.setText(mCategories[position]);
ImageView icon = (ImageView) rowView.findViewById(R.id.my_spinner_dropdown_item_icon);
icon.setImageResource(mIcons[position]);
return rowView;
}
/**
* The Spinner View that is selected and shown in the *Spinner*, i.e. not the dropdown item.
* */
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View spinnerView = convertView;
if (spinnerView == null)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
spinnerView = inflater.inflate(R.layout.my_spinner_categories_spinner_item, parent, false);
}
TextView categoryText = (TextView) spinnerView.findViewById(R.id.my_spinner_item_text);
categoryText.setText(mCategories[position]);
return spinnerView;
}
}
my_spinner_categories_dropdown_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="#+id/my_spinner_dropdown_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- Stolen from android.R.layout.simple_spinner_dropdown_item -->
<TextView
android:id="#+id/my_spinner_dropdown_item_text"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="marquee" />
</LinearLayout>
my_spinner_categories_spinner_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!-- Stolen from android.R.layout.simple_spinner_dropdown_item -->
<TextView
android:id="#+id/my_spinner_item_text"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:ellipsize="marquee" />
</LinearLayout>
And finally, setting the adapter:
MyAdapter adapter = new MyAdapter(getContext(), android.R.layout.simple_spinner_dropdown_item, mCategories);
mSpinner.setAdapter(adapter);

Related

Set text color in Android Spinner

I want to change the color of the displayed selected item in my spinner in Android (targeting API level 16 and up). I have tried several solutions posted here on SO, including creating a custom layout for my spinner items and using a ColorStateList as the text color property of the custom layout, but to no avail. The spinner is shown on a semi-transparent background - therefore the custom layout for the items does not work as it adds a color to the spinner. Currently my hack solution is
if (_colorCodeSpinner.getSelectedView() != null) {
((TextView) _colorCodeSpinner.getSelectedView()).setTextColor(0xFFFFFFFF);
}
but this only works if the selected view is not null (which it is on orientation change).
I cannot believe that there isn't a simple solution for setting the text color. It seems like something you would often do. The same with changing the color of the arrow, which I currently do by
_colorCodeSpinner.getBackground().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
Am I missing something? What is the recommended way of changing the colors on a spinner?
As seen in the image, the text color of the displayed selected item in the spinner is black, but I want to change it to be white.
EDIT
To clarify: I'm not looking for some small piece of code that overrides values at runtime (like the two snippets I posted in this question). I'm looking for an actual way to do this properly (like in the XML layout or through themes). To set the text color property once so I don't have to update it every time I e.g. select an item.
Do this :
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
((TextView) parent.getChildAt(0)).setTextColor(Color.WHITE); /* if you want your item to be white */
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
You can achieve this editing styles.xml layout file. For this answer i use a new project in Android Studio, with minSdkVersion 16 and AppCompatSpinner.
styles.xml layout:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:spinnerItemStyle">#style/mySpinnerItemSelectedStyle</item>
</style>
<style name="mySpinnerItemSelectedStyle" parent="#android:style/Widget.Holo.TextView.SpinnerItem">
<item name="android:textColor">#color/spinnerTextColor</item>
</style>
And add this at colors.xml file:
<color name="spinnerTextColor">#ffffff</color>
The solution was taken from the link below. Although it's used for color spinner dropdown items, is mostly the same approach.
https://stackoverflow.com/a/22207394/6514926
This will work for you
public void onItemSelected(AdapterView<?> parent, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
item = (String) parent.getItemAtPosition(arg2);
((TextView) parent.getChildAt(0)).setTextColor(0x00000000);
}
OR
you can use selector for changing color
create one xml named my_selctor.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="black" /> <!-- pressed -->
<item android:state_focused="true"
android:color="black" /> <!-- focused -->
<item android:color="white" /> <!-- default -->
</selector>
and in your text view set it like this way
<TextView ...........
android:textColor=""#drawable/my_selctor"/>
try the following code:-
XML:-
<Spinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_margin="20dp"
android:popupBackground="#ffffff"
android:layout_height="match_parent">
</Spinner>
create a another xml for the textview
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="dshsgv"
android:padding="5dp"
android:textColor="#000000">
</TextView>
then in your activity:-
public class MainActivity extends AppCompatActivity {
Spinner spinner;
String[] cat = {"Automobile", "Automobile"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adpter = new ArrayAdapter<String> (MainActivity.this, R.layout.text, cat);
spinner.setAdapter(adpter);
}
}
declare ArrayAdapter like this and set it to your spinner:
ArrayAdapter<String> adapter_state = new ArrayAdapter<String>(this,
R.layout.simple_spinner_dropdown_item, your_strings);
adapter_state.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
_colorCodeSpinner.setAdapter(adapter_state);
and layout xml file simple_spinner_dropdown_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:gravity="left"
android:textColor="#AAA"
android:padding="5dp"
/>
this work for me
follow this link
private OnItemSelectedListener OnCatSpinnerCL = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
((TextView) parent.getChildAt(0)).setTextColor(Color.BLUE);
((TextView) parent.getChildAt(0)).setTextSize(12);
}
public void onNothingSelected(AdapterView<?> parent) {
}
};
You can use like this. This will change your icon of DropDown menu.
spinner.getBackground().setColorFilter(Color.parseColor("#FFFFFF"), PorterDuff.Mode.SRC_ATOP);
then make one TextView layout name with spinner_text.xml like this
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinnerText"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:ellipsize="marquee"
android:textColor="#fff" />
and write this code in your MainActivity.java class like
List<String> categories = new ArrayList<String>();
categories.add("Automobile");
categories.add("Business Services");
categories.add("Computers");
categories.add("Education");
categories.add("Personal");
categories.add("Travel");
ArrayAdapter adapter = new ArrayAdapter<String>(this, R.layout.spinner_text, categories);
spinner.setAdapter(adapter);
spinner.getBackground().setColorFilter(ContextCompat.getColor(this,R.color.white), PorterDuff.Mode.SRC_ATOP);
// attaching data adapter to spinner
spinner.setAdapter(adapter);

Change background color of the selected item in Android Spinner

I am working on an android app and using Spinner at many places in my app.
What I want is to change the background color of the selected item of spinner, so that one can easily identify which item is currently selected.
I have already checked this link Setting background color for Spinner Item on selection but doing so will change the selected textview background color but do not change its color in dropdown list and I want to change the background color of the selected textview when I will see the dropdown list.
I want to change the color of selected item in list not on spinner, please see the image below.
How can I do this? Please, can someone help me here?.
Thanks a lot in advanced.
You need to implement below method in your adapter class:
It will help you:
int selectedItem = -1;
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list) {
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View v = null;
v = super.getDropDownView(position, null, parent);
// If this is the selected item position
if (position == selectedItem) {
v.setBackgroundColor(Color.BLUE);
}
else {
// for other views
v.setBackgroundColor(Color.WHITE);
}
return v;
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
Now on item selected in spinner put below
selectedItem = position;
Here is solution via XML:
Spinner looks like:
<Spinner
android:id="#+id/settingsSleepingTimePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/spinner_main_button"
android:popupBackground="#color/colorPrimary"
android:textColor="#android:color/white"
android:textSize="20sp"/>
While creating spinner set setDropDownViewResource as custom layout:
adapter.setDropDownViewResource(R.layout.spinner_item);
And spinner_item.xml looks like:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/spinner"
android:textColor="#ffffff"
android:textSize="20sp" />
And finally we set #drawable/spinner like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimaryLight" android:state_hovered="true" />
<item android:drawable="#color/colorPrimaryLight" android:state_selected="true" />
</selector>
Hope my answer will be helpfull!
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="colorControlNormal">#color/spinner_background</item>
</style>
Define Spinner_background color in color folder..
Try creating a selector in the drawable, something like,
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="#color/colorPrimary" />
<item android:drawable="#android:color/transparent" />
</selector>
And set the spinner background as
android:background="#drawable/spinner_selector"
I've searched the internet for a proper solution to do this without hardcoding the background behaviour in java code.
You can achieve this (setting the selected item background color) using drawables.
What you need to do it set the dropdownViewResource to a custom layout. That layout should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/spinner_item_background"
android:gravity="left"
android:padding="8dp" />
In spinner_item_background.xml, you can define a background for each item state. For example, if you want to have a ripple effect on press, but a solid effect when selected, you can try this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Activated state is the selected item -->
<item android:state_activated="true" android:drawable="#00ff00"/>
<!-- Pressed state is the one the user is interacting with -->
<item android:state_pressed="true" android:drawable="#00ff00"/>
<!-- The rest of the items -->
<item android:drawable="#ffffff"/>
</selector>
Create an int variable public static int posOfItemSpinnerSelected in your Activity:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
posOfItemSpinnerSelected=position;
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
and in your adapter insert this code
if(position== YourActivity.posOfItemSpinnerSelected){
textView.setBackgroundColor(ContextCompat.getColor(mActivity,R.color.item_spinner_selected));
} else {
textView.setBackgroundColor(ContextCompat.getColor(mActivity,R.color.white));
}

Views in Custom ListView item don't have apptheme

Problem:
I have a custom adapter for my listview which currently contains a checkbox and an edittext. I haven't changed any themes in the res/values/styles folder. For some reason the checkbox and edittext have a different style/theme than the normal style/theme ("AppTheme").
Automatically generated theme:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
But the checkbox is white, and can only be seen when it is checked. (color is not the colorAccent set above) And the edittext has the same color the checkbox has when it is checked (green/blueish).
colors:
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
What have I tried?
I tried setting the theme/style of the container of the item and the item itself, with the xml attributes android:theme and style. Each to no avail.
Is this normal? If so, how do I change the style/theme of the listitem? If not, what could be wrong?
My listitem.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="#+id/cb_listitem"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<EditText
android:id="#+id/editText_listitem"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="9"
android:textColor="#color/black"/>
</LinearLayout>
getView in custom adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listitem_note_checkbox, null);
holder = new ViewHolder();
holder.checkBox = (CheckBox)convertView.findViewById(R.id.cb_listitem);
holder.editText = (EditText)convertView.findViewById(R.id.editText_listitem);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.editText.setText(items.get(position).note);
return convertView;
}
screenshots:
as we can see the radio buttons have the default layout, accentcolor "pink" and they have a grey outlining. but the checkbox outlining is white, and the accentcolor is blue/greenish.
You need to use the Activity's Context for anything that requires styles and attribute values from its theme. Since your Adapter's context field is initialized in its constructor, you need to instantiate your Adapter with the Activity's Context, not the Application's, so the LayoutInflater ends up with the correct one. For example:
MyAdapter adapter = new MyAdapter(MainActivity.this, list);

Navigation Drawer item background colour for selected item

I used Android Studio to implement the Navigation Drawer and I can't get the blue colour that is used to show which section we're currently in to change.
I've tried numerous things, I'm currently using a listSelector which looks like:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#color/selected" />
<item android:state_pressed="true" android:drawable="#color/highlight" />
</selector>
I've also tried state_checked. state_pressed works in this situation but the currently selected item is still blue.
EDIT:
I've been examining this more and when the adapter is created the context that is passed is getActionBar().getThemedContext() so I'm thinking if I can find the right attribute to assign to my actionbar style I can change it from there. I've tried a few different attributes with no luck. Does anyone know the exact attribute?
I've also realised if I put
<item name="android:activatedBackgroundIndicator">#drawable/nav_listview_selector</item>
in the main part of my theme and change getActionBar().getThemedContext() for getActivity.getBaseContext then I can change the color but I don't think this is the correct way. I think the themed context should be used. So if anyone knows where the activatedBackgroundIndicator could be put so that it would be used in getActionBar.getThemedContext()
EDIT2:
So the text view used for the listview is one within the SDK it looks like this:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
So I tried modifying the "?android:attr/activatedBackgroundIndicator" at the theme level but it has no effect for checked/selected/activated but it does for pressed. Does anyone know why this is? And how I can change it?
To solve this problem:
1- You don't need android:listSelector under your ListView.
2- Open (or Create) styles.xml under (res/values).
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:activatedBackgroundIndicator">#drawable/drawer_list_selector</item>
</style>
3- Under res/drawable folder create drawer_list_selector.xml file
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/light_gray_color" />
<item android:state_activated="true" android:drawable="#drawable/red_color" />
<item android:drawable="#android:color/transparent" />
</selector>
4- Under res/drawable create red_color.xml / light_gray_color.xml (or any other name) and add your desired Hex color:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#C8FF0000"/>
</shape>
5- Open your project AndroidManifest.xml and add android:theme tag (if not exist)
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
Reference / Credit: Changing Navigation Drawer Selected Item Color from default blue
To change the "Navigation Drawer item background colour for selected item" you could do it with the attribut:
colorControlHighlight
In your "styles.xml" it could look like this:
<style name="YourStyleNameFor.NavigationDrawer" parent="ThemeOverlay.AppCompat.Light">
<item name="colorControlHighlight">#color/your_highlight_color</item>
</style>
Don't forget to apply your Style in the tag:
android.support.design.widget.NavigationView
For example in your activity_main.xml it could look like this:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/navigationdrawer_header"
<!-- the following line referes to your style -->
app:theme="#style/YourThemeNameFor.NavigationDrawer"
<!-- the following two lines are maybe also interesting for you -->
app:itemIconTint="#color/gray3"
app:itemTextColor="#color/gray3"
app:menu="#menu/navigationdrawer_main" />
This is working for me:
First define a drawable item_bg.xml as:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/nav_menu_bg" />
</selector>
Then use this drawable in navigation_main_layout.xml as:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemBackground="#drawable/item_bg"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_navigation"
app:menu="#menu/navigation_main_layout_drawer" />
here is how i have done and it is working, the brief concept is maintain the position of selected item in adapter and call notifyDataSetChanged on calling notifyDatasetChanged the getView method is called again and in get view check the position on the selected position change the background view. Here is the code :
Adapter of NavigationDrawer List View
public class MenuAdapter extends BaseAdapter {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private Context mContext;
private String name;
private int profile;
private int mIcons[];
private int selectedPosition = 0;
private String mNavTitles[];
private LayoutInflater mInflater;
public MenuAdapter(String titles[], int icon[], String Name, int profile) {
mNavTitles = titles;
mIcons = icon;
name = Name;
this.profile = profile;
}
public MenuAdapter(String Titles[], int Icons[], Context mContext) {
mNavTitles = Titles;
mIcons = Icons;
this.mContext = mContext;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mNavTitles.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
TextView textView = (TextView) convertView.findViewById(R.id.rowText);
ImageView imageView = (ImageView) convertView.findViewById(R.id.rowIcon);
final LinearLayout layout = (LinearLayout) convertView.findViewById(R.id.outerLayout);
imageView.setImageResource(mIcons[position]);
textView.setText(mNavTitles[position]);
if (position == selectedPosition)
layout.setBackgroundColor(mContext.getResources().getColor(R.color.app_bg));
else
layout.setBackgroundColor(mContext.getResources().getColor(R.color.normal_bg));
return convertView;
}
public void setSelectedPosition(int position) {
this.selectedPosition = position;
}
}
in your activity do this
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
mMenuAdapter.setSelectedPosition(position - 1);
mMenuAdapter.notifyDataSetChanged();
}
}
if anyone still face any difficulty, feel free to ask.
I have implement drawer menu with custom adapter class. May be it will help someone Drawer List
<ListView
android:id="#+id/listview_drawer"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/menu_item_color"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:fadingEdge="none"
/>
drawer_list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/menu_selector"
>
<ImageView
android:id="#+id/imgIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="#drawable/ic_menu_home" />
<TextView
android:id="#+id/lblName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/imgIcon"
android:minHeight="48dp"
android:textColor="#color/menu_txt_color" />
menu_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<!-- selected -->
<item android:drawable="#color/menu_item_active_color" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="#color/menu_item_active_color" android:state_pressed="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_activated="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_checked="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_selected="true"/>
<item android:drawable="#color/menu_item_color" android:state_activated="false"/>
Add this on item click listner of listview
yourlistview.setItemChecked(position, true);
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/list_item_back_pressed" android:state_pressed="true" />
<item android:state_activated="true"><color android:color="#color/primary_blue"/></item>
<item android:drawable="#color/list_item_back_normal"/>
</selector>
In addition to providing a custom selector drawable for the listSelector, you should also set the background resource of the list item to a similar selector drawable that has different drawables for the different states.
I usually use my custom adapter that has an int selection field, and a setSelection(int) function. And in the getView function I set the background of the view according to position == selection.
Still not sure why it is that it doesn't work. But the way I found around it is to use my own simple_list_item_activated layout to be passed to the ArrayAdapter which was basically the same except for setting the text colour to white. I then replaced getActionBar().getThemedContext() with getActivity().getBaseContext() and it now has an effect.
This may not be the correct way and may have repercussions in the future, but for now I have it working the way I want it to.
I know its too late but I have solved this issue in my app.
Pls dont think it is silly, just simply change the position of "state_pressed" to top.
<item android:drawable="#drawable/list_item_bg_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_item_bg_normal" android:state_activated="false"/>
<item android:drawable="#drawable/list_item_bg_selected" android:state_activated="true"/>
In Future if anyone comes here using, Navigation Drawer Activity (provided by Studio in Activity Prompt window)
The answer is -
Use this before OnCreate() in MainActivity
int[][] state = new int[][] {
new int[] {android.R.attr.state_checked}, // checked
new int[] {-android.R.attr.state_checked}
};
int[] color = new int[] {
Color.rgb(255,46,84),
(Color.BLACK)
};
ColorStateList csl = new ColorStateList(state, color);
int[][] state2 = new int[][] {
new int[] {android.R.attr.state_checked}, // checked
new int[] {-android.R.attr.state_checked}
};
int[] color2 = new int[] {
Color.rgb(255,46,84),
(Color.GRAY)
};
ColorStateList csl2 = new ColorStateList(state2, color2);
and use this in onNavigationItemSelected() in MainActivity (you dont need to Write this function if you use Navigation Drawer activity, it will be added in MainActivity).
NavigationView nav = (NavigationView) findViewById(R.id.nav_view);
nav.setItemTextColor(csl);
nav.setItemIconTintList(csl2);
nav.setItemBackgroundResource(R.color.white);
Tip - add this code before If else Condition in onNavigationItemSelected()
This worked for me :
implemented menu drawer not by populating the navigation view with list, but with menu items.
created a drawable like this :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/drawer_menu_selector_color" android:state_checked="true"></item>
<item android:drawable="#color/drawer_menu_selector_color" android:state_activated="true"></item>
and in onCreate method , set the id of the menu item which corresponds to selected activity as checked.
and implement the drawable selector file to your navigation drawer like this
app:itemBackground="#drawable/drawer_menu_selector"
fyi : need to define your 'app' namespace.
I searched for solution on this issue, tried everything, and only this solution worked for me.
You can find it on this link https://tuchangwei.github.io/2016/07/18/The-solution-that-the-menu-item-of-Navigation-View-can-t-change-its-background-When-it-is-selected-checked/
All the credit to https://tuchangwei.github.io/

How should I increase the spinner list item font size?

This is my spinner's code:
Spinner food = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> foodadapter = ArrayAdapter.createFromResource(
this, R.array.item_array, android.R.layout.simple_spinner_item);
foodadapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
food.setAdapter(foodadapter);
This is a part of the layout file where I have created the spinner:
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/textView1" />
This is the item_array:
<resources>
<string name="item_picker">Select an iten</string>
<string-array name="item_array">
<item>Pizza</item>
<item>Burger</item>
<item>Sandwiches</item>
<item>Bread</item>
<item>Pastries</item>
<item>Snackers</item>
</string-array>
</resources>
Note: I do not want a simple_spinner_dropdown_item.
I just want to increase the size of the list items. How can I do that?
Save the below xml as spinner_layout.xml in layout folder
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinnerTarget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="13sp"
/>
change the textSize which you want.
and use the below adapter code to fill it.
Spinner food = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> foodadapter = ArrayAdapter.createFromResource(
this, R.array.item_array, R.layout.spinner_layout);
foodadapter.setDropDownViewResource(R.layout.spinner_layout);
food.setAdapter(foodadapter);
Via XML Only
Just to help others in case they are statically setting their Spinner entries in XML.
The above answers work if you're creating your Spinner via code but if you're setting your Spinner entries via XML, i.e. using android:entries, then you can adjust the text size and other attributes with the following two theme settings:
In your res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppBaseTheme" parent="android:Theme.Holo">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- For the resting Spinner style -->
<item name="android:spinnerItemStyle">
#style/spinnerItemStyle
</item>
<!-- For each individual Spinner list item once clicked on -->
<item name="android:spinnerDropDownItemStyle">
#style/spinnerDropDownItemStyle
</item>
</style>
<style name="spinnerItemStyle">
<item name="android:padding">10dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="spinnerDropDownItemStyle">
<item name="android:padding">20dp</item>
<item name="android:textSize">30sp</item>
<item name="android:textColor">#FFFFFF</item>
</style>
</resources>
The above solutions are all hard coded in the xml.
There is an alternative solution which allows you to change it programmatically.
https://stackoverflow.com/a/11494962/5089713
Once you have the TextView, you can do whatever with it, for instance change the font size.
your code then looks like
Spinner food = (Spinner) findViewById(R.id.spinner1);
CharSequence[] strings = getActivity().getResources().getTextArray(R.array.item_array);
ArrayAdapter<CharSequence> foodadapter = new ArrayAdapter<CharSequence>(getActivity(), android.R.layout.simple_spinner_item, strings){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view =super.getView(position, convertView, parent);
TextView textView=(TextView) view.findViewById(android.R.id.text1);
// do whatever you want with this text view
textView.setTextSize(20);
return view;
}
};
foodadapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
food.setAdapter(foodadapter);
private OnItemSelectedListener spinner = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
((TextView) parent.getChildAt(0)).setTextColor(Color.BLACK);
((TextView) parent.getChildAt(0)).setTextSize(10);
}
public void onNothingSelected(AdapterView<?> parent) {
}
};
If you only want to increase the size, that the dropdown is good touchable, then you simply can change the simple_spinner_item to simple_spinner_dropdown_item:
ArrayAdapter.createFromResource(this, R.array.item_array, android.R.layout.simple_spinner_dropdown_item);
---------------------------^

Categories

Resources