Change height of Preference items - android

I have a PreferenceFragment subclass. I want each one of its items (Preferences and SwitchPreferences) to have a height of 120dp. How to do that?
Here is the related code:
public class SettingsFragment extends PreferenceFragment {
public SettingsFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.main);
}
}
and
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference android:key="app_main_switch"
android:title="#string/app_name"
android:defaultValue="true"/>
<Preference android:title="#string/events_lowercase"
android:dependency="app_main_switch">
<intent android:targetPackage="hu.ppke.itk.marma.android.bead"
android:targetClass="hu.ppke.itk.marma.android.bead.EventList"/>
</Preference>
<Preference android:title="#string/filters_lowercase"
android:dependency="app_main_switch">
<intent android:targetPackage="hu.ppke.itk.marma.android.bead"
android:targetClass="hu.ppke.itk.marma.android.bead.FilterList"/>
</Preference>
<SwitchPreference android:dependency="app_main_switch"
android:key="learn_switch"
android:defaultValue="false"
android:title="#string/learning"/>
</PreferenceScreen>
Here is how it looks like now:
So I want all four items of the list to have a height of 120dp. As you can see I'm not the one creating the ListView, it's created internally. I tried to retrieve it with
findViewById(android.R.id.list)
but iterating over its elements gives Preference objects which do not allow me to set the height.

Just do it this way:
<!-- Application theme -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Min item height -->
<item name="android:listPreferredItemHeight">10dp</item>
</style>
another styling attributes that can be overridden can be found here preference item layout

Try creating a custom Preference class (you may have to do it for every type of Preference you are going to use/want height to be 120DP)
public class SwitchPref extends SwitchPreference {
Context context;
public Pref(Context context) {
super(context);
this.context = context;
}
#Override
protected View onCreateView(ViewGroup parent) {
LinearLayout layout = new LinearLayout(getContext());
LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, dpToPx(120));
layout.setLayoutParams(params1);
//if this returns just the linearlayout, you will have to add your own switch
// or reference to a layout.xml resource
return super.onCreateView(layout);
}
public int dpToPx(int dp) {
int valueInDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources()
.getDisplayMetrics());
return valueInDp;
}
}
Then, in your preference.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!--use your custom SwitchPrefence class-->
<my.package.name.SwitchPref android:key="app_main_switch"
android:title="#string/app_name"
android:defaultValue="true"/>
<Preference android:title="#string/events_lowercase"
android:dependency="app_main_switch">
<intent android:targetPackage="hu.ppke.itk.marma.android.bead"
android:targetClass="hu.ppke.itk.marma.android.bead.EventList"/>
</Preference>
<Preference android:title="#string/filters_lowercase"
android:dependency="app_main_switch">
<intent android:targetPackage="hu.ppke.itk.marma.android.bead"
android:targetClass="hu.ppke.itk.marma.android.bead.FilterList"/>
</Preference>
<my.package.name.SwitchPref android:dependency="app_main_switch"
android:key="learn_switch"
android:defaultValue="false"
android:title="#string/learning"/>
</PreferenceScreen>
Hope this helps, happy coding!

Here is how I managed to do this:
I did need to subclass Preference but MattMatt's answer didn't work.
public class HigherPreference extends Preference {
public HigherPreference(Context context) {
super(context);
}
public HigherPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected View onCreateView(ViewGroup parent) {
Resources res=getContext().getResources();
View v=super.onCreateView(parent);
v.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, res.getDimensionPixelSize(R.dimen.rowheight)));
return v;
}
}
The layout XML goes like what he provided.

Related

How to add ripple effect to preferences in android?

I am working on adding ripple effect when the preference is touched (selected). I have customized my preference by extending the ListPreference. I have tried to set the ripple effect programmatically by using RippleDrawable but I don't see the animation.
Here is my customized preference class
public class CustomListPreference extends ListPreference {
public CustomListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListPreference(Context context) {
super(context);
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
setCustomStyle(view);
}
private void setCustomStyle(View view) {
TextView titleView = (TextView) view.findViewById(android.R.id.title);
titleView.setTypeface(InitActivity.TYPEFACE_REGULAR);
TextView summary = (TextView) view.findViewById(android.R.id.summary);
summary.setTypeface(InitActivity.TYPEFACE_REGULAR);
//Setting the drawable here, but it doesn't work.
RippleDrawable drawable = (RippleDrawable) getContext().getResources().getDrawable(R.drawable.my_ripple_background);
view.setBackGround(drawable);
}
}
My preferences layout
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- opens a subscreen of settings -->
<com.abc.app.CustomListPreference
android:defaultValue="1"
android:entries="#array/sampleEntries"
android:entryValues="#array/SampleEntryValues"
android:key="some_preference"
android:title="#string/some_preferences" />
<com.abc.app.CustomCheckboxPreference
android... />
</PreferenceScreen>
My ripple xml
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/light_black_overlay"> <!--#22000000-->
<item>
<shape
android:shape="rectangle">
<solid android:color="#android:color/background_light" />
</shape>
</item>
</ripple>
Am I setting the animation for the correct view? Any ideas are appreciated. Thanks.
This is a minimal complete example for adding a custom ripple effect to a class that extends ListPreference. I just made and tested this with API 21 (5.0).
SettingsActivity (Launch Activity)
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
}
}
pref_general.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="true"
android:key="example_checkbox"
android:summary="a checkbox"
android:title="Checkbox test" />
<!-- replace with com.abc.app.CustomListPreference in your case-->
<com.timcastelijns.rippletest.CustomListPreference
android:defaultValue="1"
android:entries="#array/sampleEntries"
android:entryValues="#array/SampleEntryValues"
android:key="some_preference"
android:title="test" />
</PreferenceScreen>
arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="sampleEntries">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="SampleEntryValues">
<item>4</item>
<item>5</item>
<item>6</item>
</string-array>
</resources>
CustomListPreference
public class CustomListPreference extends ListPreference {
private Context ctx;
public CustomListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
ctx = context;
}
public CustomListPreference(Context context) {
super(context);
ctx = context;
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
setCustomStyle(view);
}
private void setCustomStyle(View view) {
RippleDrawable drawable = (RippleDrawable) ctx.getDrawable(R.drawable.my_ripple_background);
view.setBackground(drawable);
}
}
my_ripple_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#android:color/holo_blue_light">
<item android:id="#android:id/mask">
<color android:color="#android:color/white" />
</item>
</ripple>
When pressed, it shows a light blue ripple effect, as specified in the xml:
I built this example based on your code, and code from the example SettingsActivity in the android SDK samples.
Edit:
After some time in chat and trying various things, we have come to a conclusion that the problem is caused by OP's phone (Samsung S5) or it's settings. When OP tried the code in the emulator, it all worked properly.
For reference - this is how it looked in OPs phone:

onPreferenceClick listener not working / onPreferenceClick not being called

I am trying to open a website when one of my preferences is clicked (not when the preference is actually changed because there isn't one).
The problem is that the onPreferenceClick() is never called.
This is my PreferenceActivity:
public class About extends PreferenceActivity implements
OnPreferenceClickListener {
TextView tv_developer;
TextView tv_version;
String versionName;
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.about);
Preference p_developer = (Preference) findPreference("p_developer");
p_developer.setOnPreferenceClickListener(this);
Preference p_licences = (Preference) findPreference("p_licences");
p_licences.setOnPreferenceClickListener(this);
}
#Override
public boolean onPreferenceClick(Preference pref) {
// TODO Auto-generated method stub
Log.i("Anything pressed", "YES");
if (pref.getKey().equals("p_developer")) {
Log.i("p_developer", "YES");
} else {
Log.i("p_developer", "NO");
}
return true;
}
}
This is the xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="about"
android:title="About" >
<Preference
style="?android:preferenceInformationStyle"
android:key="p_licences"
android:title="p_licences" />
<PreferenceCategory android:title="Category" >
<Preference
style="?android:preferenceInformationStyle"
android:key="p_developer"
android:title="p_developer" />
</PreferenceCategory>
</PreferenceScreen>
I have also found that this does not do anything either:
<Preference android:title="#string/prefs_web_page" >
<intent android:action="android.intent.action.VIEW"
android:data="http://www.example.com" />
</Preference>
Add android:enabled="true" to Preference:
<Preference
style="?android:preferenceInformationStyle"
android:key="p2"
android:enabled="true"
android:title="p2" />
You are using:
PreferenceActivity.addPreferencesFromResource(R.layout.about);
Shouldn't it be more like:
PreferenceActivity.addPreferencesFromResource(R.xml.yourxmlfilename);
Since thae preferences you defined are not a layout.
You need to load the name of the .xml file, not the key of the preference in .xml.
So, put your preferences .xml file in the "xml" folder, and give it a name like "mypreferences.xml". Then, load it like that:
PreferenceActivity.addPreferencesFromResource(R.xml.mypreferences);
In my project, the file looks like this: (name "settings.xml")
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Your Settings" >
<Preference
android:key="delete"
android:title="Delete User"
android:summary="Deletes the user." />
<!-- and so on -->
I add it to the PreferenceActivity by calling:
PreferenceActivity.addPreferencesFromResource(R.xml.settings);
And set the onClickListener:
Preference deletePref = (Preference) findPreference("delete");
deletePref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
// do stuff
return true;
}
});
And it works.
Furthermore, you could try using a different name for title and key.
Fresh answer here.
You need to declare listener first. And then attach that listener for each(!) of end Preference objects. Like these:
final static int CAMERA_SLEEP_TIME=0,
CAMERA_TIME=1,
RESET=2;
private Preference.OnPreferenceClickListener listener =new Preference.OnPreferenceClickListener(){
#Override
public boolean onPreferenceClick(Preference preference) {
String keyLcl = preference.getKey();
if(keyLcl.equals(cameraSleepTime))
triggerPrefsDialog(CAMERA_SLEEP_TIME);
else
if (keyLcl.equals(cameraTime))
triggerPrefsDialog(CAMERA_TIME);
else
if (keyLcl.equals(reset))
triggerPrefsDialog(RESET);
else
return false;
return true;
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Resources resLcl = getResources();
cameraSleepTime=resLcl.getString(R.string.camera_sleep_time);
cameraTime=resLcl.getString(R.string.camera_time);
reset =resLcl.getString(R.string.reset);
PreferenceScreen sceenLcl = getPreferenceScreen();
PreferenceCategory pcLcl=(PreferenceCategory)sceenLcl.getPreference(1);
pcLcl.getPreference(0).setOnPreferenceClickListener(listener);
pcLcl.getPreference(1).setOnPreferenceClickListener(listener);
pcLcl=(PreferenceCategory)sceenLcl.getPreference(2);
pcLcl.getPreference(0).setOnPreferenceClickListener(listener);
l.a(pcLcl.getTitle());
}
And related preferences.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceCategory
android:title="#string/switch_mode">
<CheckBoxPreference
android:key="#string/enable_switch"
android:defaultValue="true"
android:gravity="center"
android:title="#string/is_switched"
/>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/seconds_category">
<Preference
android:key="#string/camera_time"
android:defaultValue="600000"
android:title="#string/camera_time"
/>
<Preference
android:key="#string/camera_sleep_time"
android:defaultValue="600000"
android:title="#string/camera_sleep_time"
/>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/System">
<Preference
android:key="#string/reset"
android:defaultValue="false"
android:title="#string/reset"
/>
</PreferenceCategory>
<PreferenceCategory
android:title="#string/to_be_added">
</PreferenceCategory>
For me the solution was to extend the existing PreferenceCategory class (in Support Library) and override isEnabled(). This method always returned false so I created a class called ClickablePreferenceCategory and changed it to true.
In addition to that I had to add android:selectable="true" to my custom Preference xml node. The result looks like this:
<PreferenceCategory
android:enabled="true"
android:key="#string/key_category_problem_solving"
android:selectable="true"
android:title="#string/problem_solving">
</PreferenceCategory>
And the ClickablePreferenceCategory:
public class ClickablePreferenceCategory extends PreferenceCategory {
public ClickablePreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ClickablePreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ClickablePreferenceCategory(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ClickablePreferenceCategory(Context context) {
super(context);
}
#Override
public boolean isEnabled() {
return true;
}
}

Preference items being automatically re-set?

This appears like a bug to me: When you load many switch preferences in a preference fragment, they somehow re-set themselves , when you scroll the preferences. I have separately tested this with little demo code:
/res/xml/prefs.xml (Just a bunch of switch preferences, just enough to make preferences scroll on screen) :
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="my_prefs">
<PreferenceCategory android:key="my_prefs_cat" android:title="Settings">
<SwitchPreference android:key="p1" android:title="p1" android:defaultValue="false" />
<SwitchPreference android:key="p2" android:title="p2" android:defaultValue="false" />
<SwitchPreference android:key="p3" android:title="p3" android:defaultValue="false" />
<SwitchPreference android:key="p4" android:title="p4" android:defaultValue="false" />
<SwitchPreference android:key="p5" android:title="p5" android:defaultValue="false" />
<SwitchPreference android:key="p6" android:title="p6" android:defaultValue="false" />
<SwitchPreference android:key="p7" android:title="p7" android:defaultValue="false" />
<SwitchPreference android:key="p8" android:title="p8" android:defaultValue="false" />
<SwitchPreference android:key="p9" android:title="p9" android:defaultValue="false" />
<SwitchPreference android:key="p10" android:title="p10" android:defaultValue="false" />
</PreferenceCategory>
</PreferenceScreen>
/src/Prefs.java (A simple PreferenceFragment) :
package com.example.preflistbug;
import android.os.Bundle;
import android.preference.PreferenceFragment;
public class Prefs extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
/res/layout/main.xml (Placed PreferenceFragment in Activity layout) :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.preflistbug.Prefs"
android:id="#+id/frg_prefs"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
/src/MyActivity.java (Demo Activity) :
package com.example.preflistbug;
import android.app.Activity;
import android.os.Bundle;
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Problem: If you change the first switch preference , scroll down, scroll back up, the switch is reset. Same is true for other switch preferences which scroll out of view and are visited later. (specially, in horizontal orientation)
Happens on emulator too. I'm compiling on platform version 15, ICS. As you can see in above code, this is a very simple setup, I can't find anything in this code, that might explain why this is happening.
Update
Bug reported as Issue 26194.
Update 2
It is supposed to be fixed in android L release.
I was able to reproduce this issue. I also found a workaround but I don't know why it works :)
Create a derived class from SwitchPreference like so:
public class Pref extends SwitchPreference {
public Pref(Context context) {
super(context);
}
public Pref(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Pref(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
Then, instead of using these in your prefs.xml:
<SwitchPreference ... />
You can use these instead
<com.example.preflistbug.Pref ... />
The derivation seems to somehow fixes the issue where the view recycling in the ListView-driven preference list is reusing the controls without "freeing" them from their previous Preference object first (or so I think). I'll update this answer if I figure out more.

Android PreferenceActivity Item Height

I have a PreferenceActivity with two checkboxes. Everything is working correctly, but I have a UI problem; not all of the text for the checkbox fits onto the checkbox row.
Is there a nice way to set the minimum height for these checkbox preferences without hardcoding a value?
EDIT - adding xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="alarm_set"
android:title="#string/set_alarm_title"
android:defaultValue="true" />
<CheckBoxPreference
android:key="store_pages"
android:title="#string/store_downloaded_pages_title"
android:summary="#string/store_downloaded_pages"
android:defaultValue="false" />
</PreferenceScreen>
Based off this question about text preference having the same iussue I use this class.
public class LongSummaryCheckBoxPreference extends CheckBoxPreference
{
public LongSummaryCheckBoxPreference(Context ctx, AttributeSet attrs, int defStyle)
{
super(ctx, attrs, defStyle);
}
public LongSummaryCheckBoxPreference(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
}
#Override
protected void onBindView(View view)
{
super.onBindView(view);
TextView summary= (TextView)view.findViewById(android.R.id.summary);
summary.setMaxLines(4);
}
}
In the xml it then looks like this.
<com.iforpowell.android.ipbike.LongSummaryCheckBoxPreference android:key="#string/key_distance_line_enable"
android:title="#string/title_distance_line_enable" android:summary="#string/summary_distance_line_enable"
android:defaultValue="true" />
<com.iforpowell.android.ipbike.LongSummaryCheckBoxPreference android:key="#string/key_altitude_line_enable"
android:title="#string/title_altitude_line_enable" android:summary="#string/summary_altitude_line_enable"
android:defaultValue="true" />
I have exactly the same thing for EditTextPreference which has the same problem of a max of 2 lines for the summary in Api <= 7
In the xml you can set the height to "wrap_content". At that point it will size it to fit whatever you put in it. So, something along these lines:
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox" />
This should help
Just do it this way:
<!-- Application theme -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Min item height -->
<item name="android:listPreferredItemHeight">10dp</item>
</style>
another styling attributes that can be overridden can be found here preference item layout

Text size within an PreferenceScreen

I have xml file that defines some preference screens like the following example
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="root_preferencescreen">
<PreferenceScreen android:key="general_sett" android:title="general settings" />
....
<PreferenceScreen android:key="extras_sett" android:title="extras settings" />
</PreferenceScreen>
I would like to be able to increase the font size for the text of the preference screen , but because the within a preference screen there is no android:textsize tag , i have no idea how to accomplish that !
You can simply add android:textSize inside your theme for preference screen:
e.g :
<style name="settingsTheme" parent="PreferenceThemeOverlay">
<item name="colorAccent">#color/color_ten</item>
<item name="android:background">#color/colorPrimaryLight</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:textColorPrimary">#color/colorTextBodyLight</item>
<item name="android:textColorSecondary">#color/colorTextCaptionLight</item>
<item name="android:textSize">14sp</item>
</style>
Your SettingsActivity class :
public class SettingsActivity extends AppCompatActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
toolbar = (Toolbar)findViewById(R.id.toolbar_settings);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportFragmentManager().beginTransaction()
.replace(R.id.bodylayout, new PrefsFragment())
.commit();
}
#Override
protected void onPause() {
super.onPause();
}
}
PrefsFragment class :
public class PrefsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreatePreferences(Bundle bundle, String s) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
final Context myContext = this.getActivity();
//set your theme
myContext.setTheme(R.theme.settingsTheme);
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settingspreference);
//do other stuffs
}
//.....
}
You can make a TextView layout xml that looks something like this:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/listSeparatorTextViewStyle"
android:textColor="#android:color/white"
android:id="#+android:id/title"
/>
and set the layout of your preference category in your preferences.xml like this:
<PreferenceCategory
android:title="Category Title"
android:layout="#layout/pref_category"
/>
As long as the TextView has the id #+android:id/title you can make the layout look however you want. There is also a way to do this with styles that I haven't quite figured out.

Categories

Resources