Reputation: 4437
I am developing a PreferenceActivity
with custom Preference
views. My problem is that I created a view with a ListView
and it only shows the first element. I post my code and an image:
http://imageshack.us/photo/my-images/545/sc20120307161530.png/
http://img545.imageshack.us/img545/7207/sc20120307161530.png' border='0'/>
xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="player_settings"
android:title="@string/settings_player_config" >
<EditTextPreference
android:defaultValue="@string/settings_player_default_name"
android:dialogMessage="@string/settings_player_summary"
android:dialogTitle="@string/settings_playersname"
android:key="player_name"
android:summary="@string/settings_player_summary"
android:title="@string/settings_playersname" />
</PreferenceCategory>
<PreferenceCategory
android:key="volume"
android:title="@string/settings_volume" >
<com.battleship.preferences.SeekBarPreferences
android:defaultValue="50"
android:key="volume"
android:title="@string/settings_volume" />
</PreferenceCategory>
<PreferenceCategory
android:key="shine"
android:title="@string/settings_shine" >
<com.battleship.preferences.SeekBarPreferences
android:defaultValue="50"
android:key="shine"
android:title="@string/settings_shine" />
</PreferenceCategory>
<PreferenceCategory
android:key="themeTitle"
android:title="@string/settings_group_themes" >
<com.battleship.preferences.ListPreferences android:key="theme" />
</PreferenceCategory>
<PreferenceCategory
android:key="fontsTitle"
android:title="@string/settings_group_font_size" >
<com.battleship.preferences.ListPreferences android:key="font" />
</PreferenceCategory>
</PreferenceScreen>
The Custom ListPreference:
package com.battleship.preferences;
import com.battleship.R;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;
public class ListPreferences extends Preference implements
OnCheckedChangeListener {
public ListPreferences(Context context) {
super(context);
}
public ListPreferences(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListPreferences(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onClick() {
super.onClick();
Toast t = Toast.makeText(getContext(), "HOLA!", 3);
t.show();
}
@Override
protected View onCreateView(ViewGroup parent) {
String[] contentString = new String[3];
if (getKey().equals("theme")) {
contentString = new String[] {
(getContext().getString(R.string.settings_theme_default)),
(getContext().getString(R.string.settings_theme_black)),
(getContext().getString(R.string.settings_theme_white)) };
} else {
contentString = new String[] {
(getContext().getString(R.string.settings_font_big)),
(getContext().getString(R.string.settings_font_medium)),
(getContext().getString(R.string.settings_font_little)) };
}
ListView listView = new ListView(getContext());
ArrayAdapter<String> array = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_list_item_single_choice,
android.R.id.text1, contentString);
listView.setAdapter(array);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
return listView;
}
private void updatePreference(int intRadio) {
SharedPreferences.Editor editor = getEditor();
editor.putInt(getKey(), intRadio);
editor.commit();
}
}
Upvotes: 5
Views: 1401
Reputation: 41510
The problem is that you're trying to add a ListView as an item of another ListView. ListView is used in the layout of the PreferenceActivity. Therefore it doesn't work.
I don't understand why you don't want to go with the standard solution, ListPreference. It is made exactly for the purpose of presenting a user with a list of radio buttons.
Upvotes: 0
Reputation: 2871
Don't you hate it when everyone tries to tell you that you shouldn't do it that way instead of just answering your question? Being able to dynamically generate content is crucial to app flexibility, I totally know what you're after.
This will work assuming all the ListView entries will be roughly the same height (non-pertinent parts omitted). The order is important, try to keep it as I've indicated:
import android.view.ViewGroup.OnHierarchyChangeListener;
public class ListPreferences extends Preference implements
OnCheckedChangeListener, OnHierarchyChangeListener {
private ListView listView;
private View thisView;
private int listHeight = 0;
@Override
protected View onCreateView(ViewGroup parent) {
this.setLayoutResource(R.layout.listview_preference_layout);
thisView = super.onCreateView(parent);
listView = (ListView) thisView.findViewById(android.R.id.list);
listView.setOnHierarchyChangeListener(this);
String[] contentString = new String[3];
if (getKey().equals("theme")) {
contentString = new String[] {
(getContext().getString(R.string.settings_theme_default)),
(getContext().getString(R.string.settings_theme_black)),
(getContext().getString(R.string.settings_theme_white)) };
} else {
contentString = new String[] {
(getContext().getString(R.string.settings_font_big)),
(getContext().getString(R.string.settings_font_medium)),
(getContext().getString(R.string.settings_font_little)) };
}
ArrayAdapter<String> array = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_list_item_single_choice,
android.R.id.text1, contentString);
listView.setAdapter(array);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
return thisView;
}
public void onChildViewAdded(View parent, View child) {
int childHeight = child.getMeasuredHeight();
if(childHeight > 0)
{
listHeight = listView.getAdapter().getCount() * childHeight;
thisView.setMinimumHeight(listHeight);
Log.i(TAG,"onChildViewAdded, done: "+listHeight+" "+childHeight);
}
}
public void onChildViewRemoved(View parent, View child) {
}
}
You'll also need res/layout/listview_preference_layout.xml with the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="fill_vertical|fill_horizontal|fill"
android:gravity="fill"
android:orientation="vertical"
>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:clipChildren="true"
android:isScrollContainer="true"
android:layout_gravity="fill_vertical|fill_horizontal|fill"
android:layout_weight="1"
android:choiceMode="singleChoice"/>
</LinearLayout
Upvotes: 5
Reputation: 2843
I would advise you create a custom layout for Preferences. You can then create and style your Preferences to how you like. And using the SharedPreferences
from PreferenceManager.getDefaultPreferences()
will allow you to save any changes as if you were using the normal Preferences solution.
As Malcolm suggested, you should probably adhere to the common practices, and not try to do anything to complex here.
Another suggestion, is dont use a ListView. Instead if you want all of your Views to be displayed, manually add these to a LinearLayout, which you then place inside your Preference View.
Upvotes: 0