2016-08-08 2 views
2

Ok, j'ai les exigences suivantes:Sur certaines versions d'Android, ListView à l'intérieur de PopupWindow ne reçoit pas d'événements tactiles lorsque la popup n'est pas focalisable?

  • Un EditText dans lequel si les types d'utilisateur @ un pop-up avec des suggestions apparaît
  • L'utilisateur peut continuer à taper qui filtrera les suggestions
  • L'utilisateur peut exploiter sur une suggestion qui complètera l'entrée et de rejeter le menu contextuel
  • l'utilisateur peut taper à l'extérieur du pop-up qui rejeter

Voici mon code:

 PopupWindow popupWindow = new PopupWindow(mContext); 

     // Create ListView to show the suggestions 
     ListView listView = new ListView(mContext); 
     listView.setBackgroundColor(Color.WHITE); 
     MentionsAdapter adapter = new MentionsAdapter(mContext, suggestions); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       String username = mSuggestions.get(position); 
       String mentionCompletion = username.substring(mCurrentQuery.length()).concat(" "); 
       mEditor.getText().insert(mEditor.getSelectionEnd(), mentionCompletion); 
       hideSuggestions(); 
      } 
     }); 
     mSuggestionsListView = listView; 

     popupWindow.setContentView(listView); 
     popupWindow.setFocusable(false); 
     popupWindow.setTouchable(true); 
     popupWindow.setOutsideTouchable(true); 

     popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { 

      @Override 
      public void onDismiss() { 
       clearPopupData(); 
      } 
     }); 

     Rect popupRect = calculatePopupPosition(); 
     popupWindow.setWidth(popupRect.width()); 
     popupWindow.setHeight(popupRect.height()); 
     popupWindow.showAtLocation(mEditor, Gravity.START | Gravity.TOP, popupRect.left, popupRect.top); 

     mPopupWindow = popupWindow; 

Cela fonctionne! Le problème est que cela ne fonctionne que sur certaines versions/appareils Android. Par exemple, il fonctionne sur Android 6.0 sur l'émulateur, mais il ne fonctionne pas sur le LG G4 de mon collègue avec 6.0. Il ne fonctionne pas sur Android 4.3.1 mais fonctionne sur 4.4.2. Si le PopupWindow ne peut pas être mis au point, le numéro ListViewOnItemClickListener n'est pas appelé. Si le PopupWindow est focalisable, le ListViewOnItemClickListener est appelé mais EditText ne reçoit pas les événements clavier. J'ai essayé d'innombrables combinaisons de changement de mode de mise au point/tactile sur le PopupWindow et ListView et ne pouvait pas le faire fonctionner dans ces cas.

Toutes les suggestions sur WFT se passe et comment y remédier?

Répondre

1

J'ai trouvé un moyen de réaliser ce que je veux. Comme c'est plus un hack qu'une vraie réponse à pourquoi ce comportement incohérent se produit, je ne l'accepterai pas comme une réponse. Pourtant, il peut être utile aux personnes qui cherchent à atteindre les mêmes exigences.

Ce que j'ai été remise et faire PopupWindow focusable afin de lui permettre est intégré ListView pour recevoir des événements tactiles:

popupWindow.setFocusable(true); 

Comme cela fait effectivement le ListView aussi le récepteur d'événements du clavier, je fait un OnKeyListener que vers l'avant les événements au EditText:

 listView.setOnKeyListener(new View.OnKeyListener() { 
      @Override 
      public boolean onKey(View v, int keyCode, KeyEvent event) { 
       mEditor.dispatchKeyEvent(event); 
       return false; 
      } 
     }); 

Pour ISOLEMENT est ici le code modifié complet de la question:

 PopupWindow popupWindow = new PopupWindow(mContext); 

     // Create ListView to show the suggestions 
     ListView listView = new ListView(mContext); 
     listView.setBackgroundColor(Color.WHITE); 
     listView.setOnKeyListener(new View.OnKeyListener() { 
      @Override 
      public boolean onKey(View v, int keyCode, KeyEvent event) { 
       mEditor.dispatchKeyEvent(event); 
       return false; 
      } 
     }); 
     MentionsAdapter adapter = new MentionsAdapter(mContext, suggestions); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       String username = mSuggestions.get(position); 
       String mentionCompletion = username.substring(mCurrentQuery.length()).concat(" "); 
       mEditor.getText().insert(mEditor.getSelectionEnd(), mentionCompletion); 
       hideSuggestions(); 
      } 
     }); 
     mSuggestionsListView = listView; 

     popupWindow.setContentView(listView); 
     popupWindow.setFocusable(true); 
     popupWindow.setTouchable(true); 
     popupWindow.setOutsideTouchable(true); 

     popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { 

      @Override 
      public void onDismiss() { 
       clearPopupData(); 
      } 
     }); 

     Rect popupRect = calculatePopupPosition(); 
     popupWindow.setWidth(popupRect.width()); 
     popupWindow.setHeight(popupRect.height()); 
     popupWindow.showAtLocation(mEditor, Gravity.START | Gravity.TOP, popupRect.left, popupRect.top); 

Cela semble fonctionner sur toutes les versions/tous les appareils Android. Si la mise au point visuelle des éléments du ListView n'est pas souhaitée, vous pouvez définir l'arrière-plan des éléments ListView sur une couleur ou un dessin qui ne change pas lorsque vous effectuez la mise au point.

0

J'ai résolu ce problème en définissant simplement un OnClickListener sur convertview, qui est un paramètre de la méthode getView de l'adaptateur. J'appelle ensuite la méthode onItemClick de onItemClickListener de listview.

Pas besoin de faire de popupWindow focusable.Enfait, juste en utilisant ListPopupWindow est plus facile puisque sa seule méthode à l'intérieur getView() adaptateur que nous ajoutons quelques quelques lignes de code

ListPopupWindow popupWindow = new ListPopupWindow(mContext); 

    MentionsAdapter adapter = new MentionsAdapter(mContext, suggestions); 
    popupWindow.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      String username = mSuggestions.get(position); 
      String mentionCompletion = username.substring(mCurrentQuery.length()).concat(" "); 
      mEditor.getText().insert(mEditor.getSelectionEnd(), mentionCompletion); 
      hideSuggestions(); 
     } 
    }); 
    popupWindow.setAdapter(adapter); 

MentionsAdaptergetView méthode

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if(convertView == null){ 
      convertView = LayoutInflater.from(context).inflate(,R.layout.item_user,parent,false); 

     } 
     // this is the key point of workaround 
     convertView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       popupWindow.getListView().getOnItemClickListener() 
       .onItemClick(listView, v, position, getItemId(position)); 
      } 
     }); 
     return convertView; 
    }