Mun0n
Mun0n

Reputation: 4437

Preference List only shows first element

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

Answers (3)

Malcolm
Malcolm

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

Justin Buser
Justin Buser

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

Mimminito
Mimminito

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

Related Questions