Статьи

Решение двойной головоломки ItemClick для просмотра галереи Android

Да, представление галереи устарело, однако в настоящее время действительно нет готового решения для представления галереи, представляющего собой горизонтальную прокрутку списка элементов с центральным замком. Проект Twoway-view имеет некоторый потенциал для удовлетворения этой потребности, но ему нужно время, чтобы немного подрасти .

Существует много проблем с представлением галереи, но одна из наиболее важных — это необходимость показывать контекстные меню для элемента. Если вы используете его с D-Pad (скажем, в приложении для Android TV) и долго нажимаете на элемент, используя D-PAD OK или BUTTON-A, вы получите события ItemLongClick и ItemClick, запущенные галереей. , Это давняя ошибка в приложении, которая мучила меня годами. Я наконец отследил его и создал следующую суть, которую можно применить к пользовательской версии галереи.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 * This change should work in both the original Gallery code as well as in the vairous open source
 * extensions and variations.
 *
 * Find the displatchLongPress method in the Gallery class file. and update it to the following.
 *
 * Make sure that longPressHandled is a field available to all the other methods.
 *
 */
   boolean longPressHandled =  false;
   private boolean dispatchLongPress(View view, int position, long id) {
       longPressHandled = false;
 
       if (mOnItemLongClickListener != null) {
           longPressHandled = mOnItemLongClickListener.onItemLongClick(this,
                   mDownTouchView, mDownTouchPosition, id);
       }
 
       if (!longPressHandled) {
           mContextMenuInfo = new AdapterContextMenuInfo(view, position, id);
           longPressHandled = super.showContextMenuForChild(this);
       }
 
       if (longPressHandled) {
           performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
       }
 
       return longPressHandled;
   }
 
   /**
    * Find the onKeyUp method and change it to the following.
    *
    * Since dispatchLongPress is fired before the onKeyUp event, we have
    * to check to see if the onItemLongClickListener handled the event.
    * If so do not performItemClick, and always reset the longPressHandled to false.
    *
    */
   @Override
   public boolean onKeyUp(int keyCode, KeyEvent event) {
       switch (keyCode) {
       case KeyEvent.KEYCODE_DPAD_CENTER:
       case KeyEvent.KEYCODE_ENTER: {
 
           if (mReceivedInvokeKeyDown) {
               if (mItemCount > 0) {
 
                   dispatchPress(mSelectedChild);
                   postDelayed(new Runnable() {
                       @Override
                       public void run() {
                           dispatchUnpress();
                       }
                   }, ViewConfiguration.getPressedStateDuration());
 
                   int selectedIndex = mSelectedPosition - mFirstPosition;
 
                   if (!longPressHandled) {
                       performItemClick(getChildAt(selectedIndex),
                               mSelectedPosition,
                               mAdapter.getItemId(mSelectedPosition));
                   }
               }
           }
 
           // Clear the flag
           mReceivedInvokeKeyDown = false;
           longPressHandled = false;
 
           return true;
       }
       }
 
       return super.onKeyUp(keyCode, event);
   }

По сути, происходит то, что событие onKeyUp, которое инициировало событие ItemClick, никогда не проверялось, чтобы увидеть, обработало ли событие dispatchLongPress событие. Так что это всегда вызывало событие ItemClick. Суть делает это небольшое изменение и фактически устраняет многочисленные обходные пути, которые нужно было сделать, чтобы контекстные меню отображались в галерее.

Эта ошибка влияет только на вас, если вам нужно использовать D-PAD, пульт дистанционного управления или игровой контроллер в качестве устройства ввода. Обычные события сенсорного экрана обрабатываются правильно.