setFocus() вызывает два нажатия для выбора изображения

Я разрабатываю игровое приложение для Android, и у меня есть HorizontalScrollView, который заполняется ImageViews. Каждый ImageView можно щелкнуть, чтобы выбрать уровень, на котором вы хотите играть. Я использую SavedPreference для отслеживания последнего сыгранного уровня и использую его для определения того, какое изображение отображается на экране при загрузке меню. Таким образом, если вы находитесь на уровне 30, вам не нужно каждый раз прокручивать весь путь от уровня 1.

Я использую requestFocus(), чтобы вывести ImageView на экран, и он работает нормально, за исключением двух относительно незначительных (но раздражающих) проблем.

Вот что я делаю в своем цикле for, который заполняет { HorizontalScrollView`:

        final ImageView iv = new ImageView(LevelSelect.this);
        iv.setImageResource(levelImages[i]);
        iv.setFocusable(true);
        iv.setFocusableInTouchMode(true);
        iv.setId(i);
        LinearLayout ll= (LinearLayout)findViewById(R.id.levelSelectGallery);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(300, LinearLayout.LayoutParams.MATCH_PARENT);

и я делаю его кликабельным:

       String str = getString(R.string.level) + i + getString(R.string.avail);
       if (storage.getBoolean(str,false)) { //check if level is available (unlocked)
       iv.setClickable(true);
       final int finalI = i;
       iv.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               editor.putInt(getString(R.string.Current_Level_savepreferences), finalI); //set current level to clicked image
               Intent intent = new Intent(LevelSelect.this, LevelStart.class);
               LevelSelect.this.startActivity(intent); // begin LevelStart activity
           }
       });
       } else {
           iv.setImageResource(lockedImages[i]); // show locked image
       }

и вне цикла я устанавливаю фокус:

 //check if there is a saved level
 focusLevel = storage.getInt(getString(R.string.Saved_Level), 5); 
 //set focus on saved level
 findViewById(focusLevel).requestFocus(); 

Это переносит сфокусированный элемент на экран, но только на край. Я бы предпочел, чтобы он был по центру, если это возможно. Хотя я могу жить с этим. Основная проблема заключается в том, что кажется, что при установке фокуса теперь требуется два нажатия на изображение, чтобы вызвать onClickListener. Я предполагаю, что первое нажатие меняет фокус, а второе — щелчок. Если я удалю код, связанный с фокусом, для этого потребуется всего одно нажатие.

Есть ли лучший способ прокрутить вид до нужного изображения или что-то другое, что я должен делать с фокусировкой?


person Scott Strosahl    schedule 26.01.2015    source источник


Ответы (2)


Почему бы вам просто не поместить focusLevel внутрь onClickListener? Таким образом, нажатие на изображение фокусирует его автоматически.

person Ethan    schedule 26.01.2015
comment
OnClickListener находится внутри цикла for, поскольку он создается для каждого ImageView, который создается в цикле. Разве добавление focusLevel внутри цикла не создаст его для каждого изображения? Кроме того, нажатие на изображение уже фокусирует его. Но мне и не нужно его фокусировать. Я просто использовал requestFocus для прокрутки HorizontalScrollView до нужного изображения. - person Scott Strosahl; 27.01.2015
comment
Правильно, наверное. Извини, Скотт, тогда я не уверен - person Ethan; 27.01.2015

Итак, я не нашел способа обойти проблему двойного нажатия, когда элемент находится в фокусе, но я нашел другое решение, которое работает в моей ситуации. Вместо использования HorizontalScrollView с LinearLayout теперь я реализовал ViewPager, который центрирует мои ImageView для меня, а также позволяет мне программно прокручивать элемент с помощью setCurrentItem(). Мне вообще не нужно использовать фокусировку.

Для тех, кто хочет сделать то же самое, мне очень помог пример Филиппа: ">Как реализовать ViewPager с разными фрагментами/макетами

person Scott Strosahl    schedule 28.01.2015