質問

Using a custom ListPreference, I'm trying to ask the user to choose between 2 pre-defined values, and a custom value he can set using an edittext. Everything seems to work, except that the keyboard doesn't show up when I click on the EditText. However, the EditText seems to gain focus, as it would normally.

Here is the image of what I'm obtaining (see the focus seems to be alright) https://www.dropbox.com/s/isejjkveonwnb3f/Screenshot_2013-05-30-21-43-41.png

Here is the layout of the custom list preference row:

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

And here is my CustomListPreference code:

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
                         */
                        }
                    }
                });
            }
        }
    }
}

Note that this was based on another answered found here: custom row in a listPreference?

Edit: I've added a few code above (see onPrepareDialogBuilder), because it might come from the Dialog built.

役に立ちましたか?

解決

Ok, I managed to solve this out.

As said here: https://stackoverflow.com/a/9118027/1376834

The problem seems to be (at least in my case), that since the place where you enter text is hidden initially (or nested or something), AlertDialog is automatically setting the flag WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM (or some combination of that and WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) so that things don't trigger a soft input to show up.

So I just added getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); in my CustomHolder constructor, so that the Dialog is already built when I do so.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top