0

我对我的应用程序中使用的字体有一个对话框首选项。基本布局是一个 ListView,其中每一行由一个显示字体预览的 textView 和一个指示当前选择的字体的单选按钮组成。我希望用户能够通过单击行上的任意位置来设置首选项,但目前它仅在用户不单击单选按钮时才有效。有趣的是,一旦发生其他一些输入事件(例如滚动),单选按钮上的点击都会被处理。

这是我的代码:

ListView 的 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" >

<ListView
    android:id="@+id/fontStyleListView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true" >
</ListView>

</LinearLayout>

每一行:

<?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" >

<RadioButton
    android:id="@+id/radioButton1"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:focusable="false"
    android:focusableInTouchMode="false" />

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_toLeftOf="@id/radioButton1"
    android:ellipsize="end"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:maxLines="1"
    android:paddingLeft="20dp" />

</RelativeLayout>

爪哇:

public class FontStylePreference extends DialogPreference
{
LayoutInflater li = LayoutInflater.from( getContext() );
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences( getContext() );

String[] fontStyleEntries = getContext().getResources().getStringArray( R.array.fontstyle_entries );
String[] fontStyleEntryValues = getContext().getResources().getStringArray( R.array.fontstyle_entryValues );

ListView listView;

public FontStylePreference(Context context, AttributeSet attrs)
    {
    super( context, attrs );
    }

@Override
protected View onCreateDialogView()
    {
    super.onCreateDialogView();

    LinearLayout layout = (LinearLayout) li.inflate( R.layout.fontstylepreference, null );
    listView = (ListView) layout.getChildAt( 0 );

    // Set adapter for contents.

    FontStyleAdapter fontStyleAdapter = new FontStyleAdapter();
    listView.setAdapter( fontStyleAdapter );

    // Set onItemClickListener

    ListViewItemClickListener listener = new ListViewItemClickListener();
    listView.setOnItemClickListener( (android.widget.AdapterView.OnItemClickListener) listener );

    return layout;
    }

@Override
protected void onPrepareDialogBuilder(Builder builder)
    {
    builder.setPositiveButton( null, null );

    super.onPrepareDialogBuilder( builder );
    }

class FontStyleAdapter implements ListAdapter
    {
    ArrayList<RelativeLayout> radioTextViewArray = new ArrayList<RelativeLayout>( fontStyleEntries.length );

    /**
     * Constructor for FontStyleAdapter. Initializes contents of adapter.
     */
    public FontStyleAdapter()
        {
        // get current font style so we know which one to check.

        String currFontStyle = sharedPrefs.getString( getContext().getString( R.string.pref_key_font_style ),
            "DejaVuSans" );

        RelativeLayout row;
        TextView textView;
        RadioButton radioButton;

        Typeface typeFace;
        int fontSize = Integer
            .valueOf( sharedPrefs.getString( getContext().getString( R.string.pref_key_font_size ), "14" ) );

        if ( fontSize < 14 )
            {
            fontSize = 14;
            }

        for ( int i = 0; i < fontStyleEntries.length; i++ )
            {
            row = (RelativeLayout) li.inflate( R.layout.fontstylepreference_row, null );

            radioButton = (RadioButton) row.getChildAt( 0 );
            radioButton.setOnClickListener( new RadioButtonClickListener() );
            textView = (TextView) row.getChildAt( 1 );

            // set contents and style of each textView

            textView.setText( fontStyleEntries[i] );
            textView.setTextSize( TypedValue.COMPLEX_UNIT_PT, (float) (fontSize / 2) );
            typeFace = Typeface.createFromAsset( getContext().getAssets(), "Fonts/" + fontStyleEntryValues[i]
                + ".ttf" );
            textView.setTypeface( typeFace );

            if ( currFontStyle.equals( fontStyleEntryValues[i] ) )
                {
                radioButton.setChecked( true );
                }

            radioTextViewArray.add( row );
            }
        }

    @Override
    public int getCount()
        {
        return fontStyleEntries.length;
        }

    @Override
    public Object getItem(int position)
        {
        return radioTextViewArray.get( position );
        }

    @Override
    public long getItemId(int position)
        {
        return radioTextViewArray.get( position ).getId();
        }

    @Override
    public int getItemViewType(int position)
        {
        // Leave this as 0 to indicate we only use one type of view in this
        // list.

        return 0;
        }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
        {
        convertView = radioTextViewArray.get( position );

        int minHeight = (int) (50 * getContext().getResources().getDisplayMetrics().density);
        convertView.setMinimumHeight( minHeight );
        return convertView;
        }

    @Override
    public int getViewTypeCount()
        {
        // Leave this as 1 to indicate we only use one type of view in this
        // list.

        return 1;
        }

    @Override
    public boolean hasStableIds()
        {
        return false;
        }

    @Override
    public boolean isEmpty()
        {
        return radioTextViewArray.isEmpty();
        }

    @Override
    public void registerDataSetObserver(DataSetObserver observer)
        {
        }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer)
        {
        }

    @Override
    public boolean areAllItemsEnabled()
        {
        return true;
        }

    @Override
    public boolean isEnabled(int position)
        {
        return true;
        }

    }

class ListViewItemClickListener implements OnItemClickListener
    {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
        String font = fontStyleEntryValues[position];

        sharedPrefs.edit().putString( getKey(), font ).commit();

        Dialog dialog = (Dialog) getDialog();

        if ( dialog != null )
            {
            dialog.dismiss();
            }

        }

    }

class RadioButtonClickListener implements OnClickListener
    {

    @Override
    public void onClick(View v)
        {
        int position = listView.getPositionForView( v );

        if ( position != AdapterView.INVALID_POSITION )
            {
            String font = fontStyleEntryValues[position];

            sharedPrefs.edit().putString( getKey(), font ).commit();

            // Check if we can get the dialog. A few times the program has crashed here, maybe
            // because it is already dismissed.

            Dialog dialog = (Dialog) getDialog();
            if ( dialog != null )
                {
                dialog.dismiss();
                }
            }

        }
    }

}
4

1 回答 1

0

我遇到了类似的问题 - 在 DialogPreference 中显示的行中带有文本和按钮的列表视图不可点击(用于短按列表元素的侦听器没有响应)。环境

android:focusable="false" 

for 按钮没有帮助。但是设置

myButton.setFocusable(false);

在 listview 适配器代码中成功了。

于 2014-10-03T19:59:41.303 回答