Android edittext в listview теряет фокус на вызове notifydatachanged

17

У меня есть несколько edittext в списке. У меня есть общий фокусщик на edittext, который обновляет значение модели данных, а также фон edittext, когда фокус теряется, вызывая notifydatachanged. Проблема в том, что если один из edittext удерживает фокус, когда я касаюсь следующего edittext, он мгновенно набирает фокус, а затем теряет фокус. Я подозреваю, что это связано с вызовом метода notifydatachanged, который вызывает перерисовывание всех просмотров, после чего фокус теряется. Кто-нибудь имеет предложение или работу по этому вопросу? Спасибо.

    
задан g t 02.03.2012 в 03:12
источник

5 ответов

17

Это действительно происходит потому, что все представления перерисовываются, поэтому текст редактирования, представляющий любую строку, которая была сфокусирована, теперь представляет собой совершенно другой объект. Задайте переменную в вашем адаптере: int nowFocusedRow;

в getView для вашего адаптера: добавьте прослушиватель onFocusChanged для каждого текста редактирования и, когда этот текст редактирования получит фокус, установите в настоящее времяFocusedRow = любую строку, в которой находится сфокусированный текст редактирования. Также установите любой текст редактирования, который находится в текущейFocusedRow, чтобы быть сосредоточены.     

ответ дан Sam Judd 02.03.2012 в 06:38
источник
  • Элегантное и эффективное решение. Благодаря! :) –  g t 02.03.2012 в 12:11
  • Привет всем и @Monkeyless, приняв вышеуказанное решение, я столкнулся с другой проблемой. В моем списке также есть несколько прядильщиков, но я заметил, что если косвенник коснется после того, как какой-либо редактор был сфокусирован раньше, вращатель не будет устанавливать выделение, даже если отображается диалог выбора. Поскольку я подозреваю, что из-за того, что фокус все еще установлен на последний edittext, я попытался очистить переменную currentfocusedrow, как только любой edittext запросил фокус. Однако это не устранило проблему. Любое понимание этого? –  g t 05.03.2012 в 16:47
  • У меня такая же проблема и я понимаю решение, но не могу получить этот рабочий - относительный новичок на Android, хотя любые указатели / код были бы большой помощью. Любой шанс наклеить какой-то код - особенно прослушиватель onFocusedChanged. Заранее спасибо. –  Kern 12.07.2012 в 07:02
  • Это решение не может работать: когда Android меняет фокус без касания (прокрутка списка), currentFocusedRow будет установлен в новую строку, теряя фактическую информацию. –  3c71 30.04.2013 в 08:10
  • Шедевр, большое спасибо. –  user1510006 14.03.2015 в 21:56
18

Set

android:windowSoftInputMode="adjustPan"

для вашей деятельности в AndroidManifest.xml

    
ответ дан Rakesh 05.12.2012 в 11:04
источник
  • Это работает с фокусом, но если список длиннее экрана и вы начинаете вводить текст, поле EditText будет перемещаться из видимой области пользователя, поэтому он не видит, что он на самом деле печатает после его запуска ввод первого символа. (Android 4.1) –  Mathias Conradt 14.04.2013 в 21:42
  • tihs работал для меня, но я понятия не имею, почему и в чем проблема: / –  Nemanja Kovacevic 05.07.2013 в 12:28
  • @PadmaKumar У меня есть editText в заголовке recyclerview. Когда я вызываю notifydatastatechanged, он потерял фокус от этого текста редактирования. Поэтому мне нужно снова нажать на этот текст редактирования, чтобы сосредоточиться на этом и напечатать. Пожалуйста, дайте мне знать решение для этого. –  iDroid Explorer 08.09.2016 в 05:31
6

У меня также была проблема с EditText, потерявшей фокус, но вызов setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS) решил его.

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    final ListView lv = getListView();
    lv.setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS);
}
    
ответ дан Y2i 06.10.2012 в 03:42
источник
  • Это работает только для одного EditText в списке, но если каждый элемент списка имеет такой элемент EditText, и я нажимаю EditText во второй строке, фокус - после отображения экранной клавиатуры - будет в EditText первая строка списка, но она должна быть во второй. (Android 4.1) –  Mathias Conradt 14.04.2013 в 21:43
1

Для будущих пользователей все здесь сложно. Правильный ответ: добавить

android:descendantFocusability="afterDescendants"

в список.

    
ответ дан Gabe Sechan 21.09.2016 в 17:36
источник
0

Пример реализации предложения Сэма Джадда с дополнительным переключателем use_last_focus

public class my_friends_adapter extends ArrayAdapter<group_user> {
    boolean use_last_focus=false;
    int currentlyFocusedRow=-1;
    String currentlyFocusedField="";

    public my_friends_adapter(Context context, int resource, ArrayList<group_user> users) {
            super(context, resource, users);
              }
        EditText tvName,tvEmail;

    @Override
   public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) convertView = LayoutInflater.from(getContext()).inflate(R.layout.my_friends_item, parent, false);
        tvName = (EditText) convertView.findViewById(R.id.tvName);
        tvEmail = (EditText) convertView.findViewById(R.id.tvEmail);
        if (use_last_focus && currentlyFocusedRow ==position){
            if (currentlyFocusedField=="tvName")tvName.requestFocus();
            else tvEmail.requestFocus();
            use_last_focus=false;
        }
        tvName.setTag(position);//When focus is lost save the entered value for later use
        tvName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {save_data2( v,  hasFocus);
            }
        });

        tvEmail.setTag(position);//When focus is lost save the entered value for later use
        tvEmail.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {save_data2( v,  hasFocus);}
        });

        return convertView;
        }


    public  void save_data2(View v, boolean hasFocus){
        int position = (Integer) v.getTag();
        EditText tvName1 = (EditText) v.findViewById(R.id.tvName);
        EditText tvEmail1 = (EditText) v.findViewById(R.id.tvEmail);
        boolean data_changed=false;
        if (hasFocus) currentlyFocusedRow=position;
        if (!(tvName1==null)) {
            if (hasFocus) currentlyFocusedField="tvName";
        }
        if (!(tvEmail1==null)) {
            if (hasFocus) currentlyFocusedField="tvEmail";
        }
        // set when data_changed
        // ..........
        if (!hasFocus && data_changed) {
            //your code to save the changed data
            // ...............
            //
            my_friends.adapter.notifyDataSetChanged();
            use_last_focus=true;
        }

    }



}
    
ответ дан tsig 12.04.2017 в 11:13
источник