2

使用自定义 ListPreference,我试图让用户在 2 个预定义值和他可以使用编辑文本设置的自定义值之间进行选择。一切似乎都正常,除了当我点击 EditText 时键盘没有出现。但是,EditText 似乎像往常一样获得了焦点。

这是我得到的图像(看到焦点似乎没问题) https://www.dropbox.com/s/isejjkveonwnb3f/Screenshot_2013-05-30-21-43-41.png

这是自定义列表首选项行的布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingBottom="8dip"
    android:paddingTop="8dip"
    android:paddingLeft="10dip"
    android:paddingRight="10dip">



    <EditText
        android:id="@+id/ET_prefs_customText"
    android:layout_width="0dip"
    android:layout_weight="1"
    android:hint="@string/SP_address_hint"
    android:layout_height="wrap_content"
        />
            <RadioButton
                android:id="@+id/custom_list_view_row_radio_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false" />

</LinearLayout>

这是我的 CustomListPreference 代码:

public class CustomListPreference extends ListPreference
{   
    /*
     * removed useless stuff
    */
        @Override
protected void onPrepareDialogBuilder(Builder builder)
{
    entries = getEntries();
    entryValues = getEntryValues();

    if (entries == null || entryValues == null || entries.length != entryValues.length )
    {
        throw new IllegalStateException(
                "ListPreference requires an entries array and an entryValues array which are both the same length");
    }

    customListPreferenceAdapter = new CustomListPreferenceAdapter(mContext);

    builder.setAdapter(customListPreferenceAdapter, new DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface dialog, int which)
        {

        }
    });
}

    private class CustomListPreferenceAdapter extends BaseAdapter
    {        
        private SharedPreferences prefs;
        public CustomListPreferenceAdapter(Context context)
        {
            this.prefs = PreferenceManager.getDefaultSharedPreferences(context);

        }

        /*
         * removed usual adapter stuff (getCount, getItem...)
         */

        public View getView(final int position, View convertView, ViewGroup parent)
        {  
            View row = convertView;

            if(row == null)
            {
                //If it's not the last one: use a normal holder...
                if(position < 2)
                {
                    NormalHolder holder = null;

                    row = mInflater.inflate(R.layout.normal_list_preference_row, parent, false);
                    if(prefs.getString(mContext.getString(R.string.SP_address), "0").equals(entryValues[position])) {
                        holder = new NormalHolder(row, position,true);
                    } else {
                        holder = new NormalHolder(row, position,false);
                    }


                    row.setTag(holder);
                    row.setClickable(true);
                    row.setOnClickListener(new View.OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            for(RadioButton rb : rButtonList)
                            {
                                if(rb.getId() != position)
                                    rb.setChecked(false);
                            }

                            int index = position;
                            String value = entryValues[index].toString();
                            Log.v("Editor", "putting string" + value);
                            editor.putString(mContext.getString(R.string.SP_address), value);
                            editor.commit();
                            Dialog mDialog = getDialog();
                            mDialog.dismiss();
                        }
                    });
                    //Otherwise, if it is the last one...
                } else {
                    //Use the custom row
                    row = mInflater.inflate(R.layout.custom_list_preference_row, parent, false);
                    String fromPref = prefs.getString(mContext.getString(R.string.SP_address), "0");
                    boolean flag=false;
                    for(CharSequence entry  : entryValues) {
                        if(entry.toString().equals(fromPref)) {
                            flag=true;
                        }
                    }
                    //And use a "custom holder"
                    CustomHolder holder;
                    if(!flag) {
                        holder = new CustomHolder(row, position, fromPref, true);
                    } else {
                        holder = new CustomHolder(row, position, "", false);

                    }
                    row.setTag(holder);
                }
            }

            return row;
        }
        /*
         * This class just shows the information in row from the position and the PreferenceList entries
         */
        class NormalHolder
        {
             private TextView text = null;
             private RadioButton rButton = null;

             NormalHolder(View row, int position, boolean isCheked)
             {    
                 text = (TextView)row.findViewById(R.id.custom_list_view_row_text_view);
                 text.setText(entries[position]);
                 rButton = (RadioButton)row.findViewById(R.id.custom_list_view_row_radio_button);
                 rButton.setId(position);
                 rButton.setChecked(isCheked);

                 // also need to do something to check your preference and set the right button as checked

                 rButtonList.add(rButton);
                 rButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
                 {
                     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
                     {
                         if(isChecked)
                         {
                        /*
                         * Put stuff into SharedPreference
                         */
                         }
                     }
                 });
             }

        }
        /*
         * This class display the text within the EditText
         */
        class CustomHolder
        {
            private EditText text = null;
            private RadioButton rButton = null;

            CustomHolder(View row, int position, String pref, boolean checked)
            {    
                text = (EditText)row.findViewById(R.id.ET_prefs_customText);
                text.setText(pref);

                rButton = (RadioButton)row.findViewById(R.id.custom_list_view_row_radio_button);
                rButton.setId(position);
                rButton.setChecked(checked);

                rButtonList.add(rButton);
                rButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
                {
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
                    {
                        if(isChecked)
                        {
                        /*
                         * Put stuff into SharedPreference
                         */
                        }
                    }
                });
            }
        }
    }
}

请注意,这是基于此处找到的另一个答案:listPreference 中的自定义行?

编辑:我在上面添加了一些代码(请参阅 参考资料onPrepareDialogBuilder),因为它可能来自构建的 Dialog。

4

1 回答 1

0

好的,我设法解决了这个问题。

如此处所述:https ://stackoverflow.com/a/9118027/1376834

问题似乎是(至少在我的情况下),因为您输入文本的位置最初是隐藏的(或嵌套的或其他东西),AlertDialog 会自动设置标志 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM (或它和 WindowManager 的某种组合.LayoutParams.FLAG_NOT_FOCUSABLE),这样事情就不会触发软输入显示。

所以我只是 getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 在我的CustomHolder构造函数中添加了,这样当我这样做时对话框就已经构建好了。

于 2013-05-30T21:58:56.417 回答