Поведение фокуса элементов ListView - PullRequest
1 голос
/ 23 января 2012

Я пытаюсь создать ListView (с пользовательским CursorAdapter) из EditText элементов, так что EditTexts сначала будет недоступен для редактирования и станет доступным для редактирования при длинном щелчке.Затем пользователь будет редактировать EditText содержимое, а EditText будет сохранять изменения в дБ при потере фокуса.Однако я столкнулся с очень неприятным поведением, которое мешает мне сделать это.

1) Я установил свои EditTexts на android:focusable="false" и android:focusableInTouchMode="false" в XML.

2) Я создал OnItemLongClickListener в моем ListActivity, который выполняет следующее:

public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
    Log.d("NLAc", "longClick called");
    EditText et = (EditText) view.findViewById(R.id.etFolderName);
    et.setFocusable(true);
    et.setFocusableInTouchMode(true);
    return true;
}

3) И когда я создаю представления в моем адаптере, я прикрепляю следующий фокуссменить слушателя:

public void onFocusChange(View v, boolean hasFocus) 
{
    if (hasFocus)
{
    EditText et = (EditText)v;
    Log.d(TAG, "hasFocus true called " + et.getText());
    et.setText("focused");
    et.setSelection(et.length());
}
else
{
    EditText et = (EditText)v;
    Log.d(TAG, "hasFocus false called " + et.getText());
    et.setText("unfocused");
    et.setFocusableInTouchMode(false);
            //TODO Save to DB
}

} ​​

В результате, когда я долго щелкаю по самому первому элементу, в журнале появляется следующее:

longClick called

hasFocus true called item1

hasFocus false called focused

Если я удаляю настройку линии с фокусировкой на false (et.setFocusableInTouchMode(false);), я получаю еще hasFocus true called unfocused.Очевидно, что дела идут так:

1) EditText получает фокус при настройке фокусировки

2) LinearLayour, содержащий мой ListView, теряет фокус и вызывает внутренний unFocus() для всех своих детейвключая мой EditText

3) EditText теряет фокус

4) EditText получает фокус - по любой причине сейчас.

Это поведение не позволяет мне отключить EditText при потере фокуса или отключении фокуса до следующего длинного щелчка, чего я и хочу.Кто-нибудь может подсказать, чего мне не хватает?Или объяснить это поведение?Любые решения приветствуются.

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Мне удалось добиться некоторого прогресса, используя два представления друг над другом. Я использую TextView для несфокусированного отображения, и я скрываю его и показываю EditText вместо долгого нажатия. Но сначала это не помогло с очень странной обработкой фокуса ListView, пока я не поэкспериментировал с настройкой android:descendantFocusability, определенной для ViewGroups. После того, как я установил его на ViewGroup.FOCUS_AFTER_DESCENDANTS, его поведение стало намного более предсказуемым, по крайней мере, для меня.

1 голос
/ 24 января 2012

OK.Вот твой код.надеюсь, что это соответствует вашим потребностям или, по крайней мере, это то, что я получил из вашего поста:)


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.view.*;
import android.widget.*;
import java.util.ArrayList;
import java.util.List;

public class EditListActivity extends Activity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        ll.setLayoutParams(lp1);
        ll.setOrientation(1);
        ListView lv = new ListView(this);
        MyListAdapter adapter = new MyListAdapter(this, null);
        lv.setAdapter(adapter);
        ll.addView(lv);
        setContentView(ll);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


    class MyListAdapter extends BaseAdapter implements View.OnLongClickListener, View.OnFocusChangeListener {
        private final String TAG = ListActivity.class.getName();
        List<String> stringsarray;
       private Context context;

        public MyListAdapter(Context context, List<String> phonebook) {
            this.stringsarray = new ArrayList<String>();

            this.stringsarray.add("test1");
            this.stringsarray.add("test2");
            this.stringsarray.add("test3");
            Log.d(TAG, "created list adapter");
            this.setContext(context);
        }

        public int getCount() {
            return this.stringsarray.size();
        }

        public String getItem(int position) {
            return this.stringsarray.get(position);
        }

        public long getItemId(int position) {
            return position;
        }


        public View getView(final int position, View convertView, ViewGroup parent) {
            LinearLayout rl = new LinearLayout(getContext());

            rl.setOrientation(1);
            EditText text = new EditText(getContext());

            text.setOnLongClickListener(this);
            text.setOnFocusChangeListener(this);
            text.setText(this.stringsarray.get(position));

            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);

            text.setFocusable(true);
            rl.addView(text, lp);
            return rl;
        }

        public void onFocusChange(View view, boolean b) {
            EditText et = (EditText) view;
                et.setFilters(new InputFilter[]{
                        new InputFilter() {
                            public CharSequence filter(CharSequence src, int start,
                                                       int end, Spanned dst, int dstart, int dend) {
                                return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
                            }
                        }
                });
            if (b) {
                Log.d(TAG, "hasFocus true called " + et.getText());
                et.setText("focused");
                et.setSelection(et.length());

            } else {

                Log.d(TAG, "hasFocus false called " + et.getText());
                et.setText("unfocused");
                //TODO Save to DB
            }
        }

        public boolean onLongClick(View view) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            final EditText et = (EditText) view;
            et.setFilters(new InputFilter[]{
                        new InputFilter() {
                            public CharSequence filter(CharSequence src, int start,
                                                       int end, Spanned dst, int dstart, int dend) {
                               return src;
                            }
                        }
                });
            et.setText("editable");
            Log.d(TAG, "on long click called " + et.getText());
            et.requestFocus();
            et.setFocusableInTouchMode(true);

            return true;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }
    }

}

весело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...