I am writing an application that SDK 10+. I would like all of my check boxes in my Activities as well as my PreferenceActivity to look the same. I created a Theme that has a Theme.Black parent. I created a child style of android:Widget.CompoundButton.CheckBox and set the android:checkboxStyle to that child theme. I have applied my theme across the entire app in the application manifest element with:
android:theme="#style/AppTheme"
When I look at the main Activity, the check box style has been applied as expected, but the checkbox in the PreferenceActivity does not have the style. My questions are:
Is it possible to style minor parts of preferences without having to specify an entire new layout for each one?
More generally, I would like to do this for other controls that show up in the preferences, like toggles or switches. Is that possible? (My guess is that the solution to one will pretty much be able to be applied to those particular issues as well)
I know there is an issue for nested preferences, but this question is applicable to Preferences at the top level. Any help is greatly appreciated. I have been banging my head against a wall on this one for a couple hours now...
Here is what I have so far:
prefs.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="checkbox1"
android:summary="This is a themed checkbox preference"
android:title="Checkbox 1" />
</PreferenceScreen>
ThemedPreferenceActivity.java
public class ThemedPreferencesActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
main.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="match_parent"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBox1"
android:text="CheckBox"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" style="#style/AppTheme.Preference.Checkbox" />
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
style.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Black">
<item name="android:checkboxStyle">#style/AppTheme.Preference.Checkbox</item>
</style>
<style name="AppTheme.Preference.Checkbox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">#drawable/pref_checkbox</item>
<item name="android:background">#FF0000</item>
</style>
</resources>
pref_checkbox.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="#android:drawable/ic_menu_call" />
<item android:state_checked="false" android:drawable="#android:drawable/ic_menu_camera" />
</selector>
Looks like the issue was with the line:
<style name="AppTheme.Preference.Checkbox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">#drawable/pref_checkbox</item>
<item name="android:background">#FF0000</item> <---- RIGHT HERE
</style>
Looks like specifying that was causing the check box to misbehave. Turns out that I didn't need that anyway (and in fact, realized I would do it in the "ListView" style anyway if I wanted it) so, problem solved.
Related
I have an Android Splash Screen which renders a drawable. When it is opened via a cold start, I find that my asset simply shifts in an upward direction.
You can find the appropriate code below, all unnecessary code has been omitted.
Here's the slight shift:
SplashActivity.java
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this, R.style.SplashTheme);
super.onCreate(savedInstanceState);
}
res/drawable/background_splash.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<item android:drawable="#color/splash_background_color"/>
<item
android:gravity="center"
>
<bitmap
android:src="#drawable/x150"/>
</item>
</layer-list>
res/layout/launch_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/splash_background_color">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/background_splash"
/>
</FrameLayout>
res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>
<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">#drawable/background_splash</item>
</style>
</resources>
I found the solution:
You should remove ImageView because you've already set splash via android:windowBackground.
Also remove android:background="#color/splash_background_color" from FrameLayout to make it transparent
Btw, you could delete res/layout/launch_screen.xml if you are not going to draw some layouts over your splash.
For Activity don't call setContentView()
For Fragment don't override onCreateView()
It's ok, Android doesn't require to set layout for them.
In styles.xml, replace:
<item name="android:windowBackground">#drawable/background_splash</item>
with
<item name="android:background">#drawable/background_splash</item>
Note the windowBackground -> background
That solves the issue for me.
I have an android.support.v4.preference.PreferenceFragment which uses the following PreferenceScreen:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Cat1"
android:key="pref_cat1">
<ListPreference
android:key="pref_list1"
android:title="#string/pref_list1"
android:dialogTitle="#string/pref_list1"
android:entries="#array/pref_list1_entries"
android:entryValues="#array/pref_list1_entries"
android:defaultValue="#string/pref_list1_default"/>
<EditTextPreference
android:key="pref_text2"
android:title="#string/pref_text2"
/>
</PreferenceCategory>
<PreferenceCategory
android:title="Cat2"
android:key="pref_cat2">
<EditTextPreference
android:key="pref_text3"
android:title="#string/pref_text3"
/>
</PreferenceCategory>
When displaying the PreferenceFragment, some dividers are shown between the preferences, but also under the name of each PreferenceCategory.
Though I can easily modify the color of the dividers between the preferences by accessing the PreferenceFragment's ListView, this has no effect on the PreferenceCategory dividers.
How to change also the color of such dividers?
I had the same problem in my Prefernces file. I solved it by the following steps:
1: Define file name preferences_category.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="vertical">
<TextView
android:id="#+android:id/title"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
<View style="#style/Divider" />
</LinearLayout>
2: Define style in the style xml file:
<style name="Divider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
<item name="android:background">#android:color/white</item>
</style>
3: add the preferences_category.xml file as android:layout attribute in the preferences xml file: :
<PreferenceCategory
android:title="My title"
android:layout="#layout/preferences_category">
You have two options:
Define the listSeparatorTextViewStyle in your app's theme
Note that anything else which relies on this theme attribute will also change to use the style you define. If that's ok with you, it will look something like this:
<style name="AppTheme" parent="android:...">
...
<item name="android:listSeparatorTextViewStyle">#style/ListSeparatorText</item>
</style>
<style name="ListSeparatorText" parent="android:Widget.TextView"><!--parent is optional -->
<item name="android:background">...</item>
...
</style>
Define a custom layout for your PreferenceCategories
The default layout for a PreferenceCategory is just a TextView. You can make your layout as simple or as complicated as you like, but somewhere should be a TextView with android:id="#android:id/title" so that the title is bound automatically.
Once you have a layout, use the android:layout attribute in your preference xml:
<PreferenceCategory
android:title="Cat2"
android:key="pref_cat2"
android:layout="#layout/my_pref_category">
...
</PreferenceCategory>
Alternatively, you can define the preferenceCategoryStyle in your app's theme, in which case you don't need to use android:layout at all in your preference xml.
<style name="AppTheme" parent="android:...">
...
<item name="android:preferenceCategoryStyle">#style/PreferenceCategoryStyle</item>
</style>
<style name="PreferenceCategoryStyle" parent="android:Preference.Category">
<item name="android:layout">#layout/my_pref_category</item>
...
</style>
Now you can also set a custom drawable for your divider in code. I'm not sure about the older versions of support libraries, but at least now with AndroidX it works for me.
In your PreferenceFragmentCompat you can add:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setDivider(getResources().getDrawable(R.drawable.your_divider_drawable, requireActivity().getTheme()));
}
Also you can call setDivider(null) to remove the separator.
I have a spinner like the image below;
How can I remove the gap on the left x between the spinner and its dropdown - preferably a solution that works on API8 as I am trying to keep my app requirements as low as possible.
I had assumed this would be layout_margin in the spinners style, but after reading this question it seems thats not possible.
In my theme I have;
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:dropDownListViewStyle">#style/DropDownStyle</item>
<item name="android:dropDownSelector">#style/DropDownStyle</item>
</style>
<style name="DropDownTopStyle">
<item name="android:clickable">true</item>
<item name="android:background">#drawable/dropdowntop</item>
</style>
<style name="DropDownStyle">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_marginLeft">0dp</item>
<item name="android:layout_margin">0dp</item>
<item name="android:clickable">true</item>
<item name="android:background">#drawable/dropdownback</item>
<item name="android:popupBackground">#drawable/dropdownback</item>
<item name="android:cacheColorHint">#FFF000</item>
</style>
Thanks,
Thomas
Additional;
I can see there might be a way to make a popup myself in code - if this is necessary, can I somehow get to the adapters popup view? (that is the list that it displays). Trying to recreate the whole adapters behavior from scratch seems a terrible way to go - but if I can get to that view and disable the normal popup behavior, then I could make my own popup without the annoying offset.
Seems you need to extend the Spinner View to make your own AlertDialog that shows the list of items, or in newer version (API 16+) you can use
android:dropDownHorizontalOffset="-8dp"
check the full details here: How to change the position of opened spinner?
Is what you want something like this?
If so, here is the code (works until API level 9) :
Activity:
public class MainActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinnerListOptions = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapterListOptions = ArrayAdapter.createFromResource(this, R.array.string_array,
R.layout.spinner_item_top);
adapterListOptions.setDropDownViewResource(R.layout.spinner_item_dropdown);
spinnerListOptions.setAdapter(adapterListOptions);
}
}
spinner_item_top.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:textSize="12sp"
android:gravity="center">
</TextView>
spinner_item_dropdown.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:textSize="12sp"
android:gravity="center">
</TextView>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
strings.xml:
<resources>
<string-array name="string_array">
<item>item 1</item>
<item>item 2</item>
<item>item 3</item>
</string-array>
</resources>
Try this, This should work
<style name="DropDownStyle">
<item name="android:layout_width">0dp</item>
I dont know it is possible, because all view item like Spinner, EditText, etc... are small images in the android SDK. You should check, is there any default padding in the 9patched SDK image, if yes, I think you cant do it.
Also, don`t forget to check the base Spinner class in Android sourcode, maybe there are some trick.
I have a listactivity with iconified text which I'm giving a custom title. Here's my custom_style.xml:
<resources>
<style name="CustomWindowTitleBackground">
<item name="android:background">#222222</item>
</style>
<style name="CustomTheme" parent="android:Theme">
<item name="android:windowTitleSize">50dip</item>
<item name="android:windowTitleBackgroundStyle">#style/CustomWindowTitleBackground</item>
</style>
</resources>
Here's the layout for the title, window_title.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:gravity="center_vertical"
android:paddingLeft="10dip"
android:background="#222222">
<ImageView
android:id="#+id/header"
android:src="#drawable/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
I set the new title style in onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
// if it wasn't a listactivity, here I'd use
// setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
browseToRoot();
}
My problem is that the styled title bar appears at the correct size and with the correct background colour (taken from custom_style.xml) but eveything in window_title.xml is ignored. The rest of the listadapter still works fine. In a very similar question here: Custom title with image it says setFeatureInt must come before super.onCreate but either way my result is the same.
I've tried replacing the imageview with a nice simple textview, but the entire window_title.xml seems to be ignored. Any ideas where I'm going wrong? Many thanks, Baz.
I have defined a style for Linear layout but the layout is not visible in graphical view of main.xml
main.xml.
<LinearLayout style="VerticalThemeLayoutInputs">
styles.xml
<resources>
<style name="VerticalThemeLayoutInputs">
<item name="android:background">#6699FF</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
</style>
</resources>
Edit:
But below code will work fine but I don't want this code
<LinearLayout
android:background="#6699FF"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
Interesting Fact
I used a scrollview. Within that I placed many Linear layout. Layouts properties are almost same so I decided to have a style for that. But what is happening know? the layout is not visible only in graphical-view but it works fine in emulator.
But actually what is happening? I think its due to Scroll view.
I think what you want is style="#style/VerticalThemeLayoutInputs".
E.g.
<LinearLayout
style="#style/VerticalThemeLayoutInputs">
main.xml in res/layout/:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/VerticalThemeLayoutInputs"
>
</LinearLayout>
styles.xml in res/values/:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="VerticalThemeLayoutInputs">
<item name="android:background">#6699FF</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:orientation">horizontal</item>
<item name="android:gravity">center_vertical</item>
</style>
</resources>
onCreate method in activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
<item name="android:layout_marginTop">#dimen/margin_top</item>
remove this tag and check.. this seems to be an invalid one.. and in main.xml add style="#style/VerticalThemeLayoutInputs" just like the above answer given by steve
Are you sure from that the style.xml located in Value folder NOT in Ar/EN/..
because he called the default in the first "value\style.xml "