2015-06-11 39 views
3

在我的Android應用程序中,我有一個EditText。當關注EditText時,顯示PopupWindow,其包含ListView。當屏幕上顯示PopupWindow時,用戶可以繼續輸入EditText,同時他/她應該能夠點擊ListView上的項目來解除PopupWindow。 (取決於ListView項目被點擊,除了解僱PopupWindow別的東西也應該發生,但它是這裏無關緊要。)Android ListView的OnItemClickListener無法處理不可聚焦的PopupWindow

的問題是,雖然「繼續輸入」的部分作品,「點擊的項目」部分沒有,因爲ListViewOnItemClickListener永遠不會被調用,我不知道爲什麼。

這裏是我的activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#ddd" 
    android:focusableInTouchMode="true" 
    tools:context="com.example.popuptest3.MainActivity" > 

    <EditText 
     android:id="@+id/edtPhone" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:inputType="phone" /> 

</RelativeLayout> 

popup_window.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#fff" > 

    <ListView 
     android:id="@+id/lstItems" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_marginBottom="60dp" /> 

    <Button 
     android:id="@+id/btnDismiss" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:text="Dismiss" /> 

</RelativeLayout> 

list_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="50dp" > 

    <TextView 
     android:id="@+id/txtItem" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:gravity="center_vertical" 
     android:text="Item Text" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

</RelativeLayout> 

在我MainActivity類,我有以下準備代碼:

private PopupWindow popup = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    prepareControls(); 
} 

private void prepareControls() { 
    final EditText edtPhone = (EditText)findViewById(R.id.edtPhone); 
    edtPhone.setOnFocusChangeListener(new OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (hasFocus) 
       openPopup(edtPhone); 
      else 
       closePopup(); 
     } 
    }); 
} 

也就是說,我打開PopupWindowedtPhone獲得焦點,並關閉PopupWindowedtPhone失去焦點。然後我有:

private void openPopup(View parent) { 
    closePopup(); 

    // Inflate the view of the PopupWindow. 
    LayoutInflater layoutInflater = LayoutInflater.from(this); 
    View view = layoutInflater.inflate(R.layout.popup_window, 
      new LinearLayout(this), false); 
    final Activity activity = this; 

    // Prepare the ListView. 
    ListView lstItems = (ListView)view.findViewById(R.id.lstItems); 
    lstItems.setAdapter(new ListAdapter(this)); 
    lstItems.setOnItemClickListener(new OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 
      hideKeyboardAndClearFocus(activity); 
     } 
    }); 

    // Prepare the Button. 
    Button btnDismiss = (Button)view.findViewById(R.id.btnDismiss); 
    btnDismiss.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      hideKeyboardAndClearFocus(activity); 
     } 
    }); 

    // Create and show the PopupWindow. 
    popup = new PopupWindow(view, 400, 300, false); 
    popup.showAtLocation(parent, Gravity.LEFT | Gravity.TOP, 0, 60); 
} 

btnDismiss按鈕不是我計劃的一部分;我只是爲了演示而添加它。最後,我有:

private void closePopup() { 
    if (popup != null) { 
     popup.dismiss(); 
     popup = null; 
    } 
} 

private static void hideKeyboardAndClearFocus(Activity activity) { 
    InputMethodManager manager = (InputMethodManager)activity. 
      getSystemService(Activity.INPUT_METHOD_SERVICE); 
    manager.hideSoftInputFromWindow(
      activity.getCurrentFocus().getWindowToken(), 0); 
    activity.getWindow().getDecorView().clearFocus(); 
} 

我覺得這不需要解釋,且ListAdapter類是很標準,所以我忽略它。

現在,當我點擊edtPhone時,它變得焦點,軟鍵盤出現,並打開PopupWindow。我可以鍵入edtPhone,當我點擊btnDismiss時,edtPhone失去焦點,軟鍵盤被解除,PopupWindow關閉,如預期的那樣。但如果不是btnDismiss我點擊lstItems上的一個項目,什麼都不會發生。使用Log我可以看到OnItemClickListener未被調用。有趣的是,ListView可以很好地滾動,它只是無法點擊。

我知道this post但該解決方案不適用於我的目的。如果我改變這一行:

popup = new PopupWindow(view, 400, 300, false); 

以下幾點:

popup = new PopupWindow(view, 400, 300, true); 

PopupWindow成爲可聚焦和ListView變成可點擊的,正常的,但我不能繼續輸入到edtPhone。事實上,如果對活動有其他控制,則它們都變得無法訪問,就好像PopupWindow是「模態」一樣。

我也試過android:focusable="false",沒有運氣。而且我沒有自動完成,因此AutoCompleteTextView不是我所需要的。

那麼爲什麼OnItemClickListener不是不可調焦的PopupWindow?我做錯了什麼?

回答

1

設置popupwindow到不可聚焦

popupwindow.setFocusable(false); 
popupwindow.setTouchable(true); 
popupwindow.setOutsideTouchable(true); 

延長ListView和重寫以下方法

@Override 
public boolean hasFocus() { 
    return true; 
} 

@Override 
public boolean isFocused() { 
    return true; 
} 

@Override 
public boolean hasWindowFocus() { 
    return true; 
} 

這是AutoCompleteTextView如何實現的建議彈出。 如果您需要使用DPAD鍵或其他導航鍵選擇列表項,則需要將EditText中的鍵事件傳遞給ListView。

+0

這是相當長一段時間以前,我已經開始了,所以恐怕我現在無法驗證你的答案。但我明白你的建議,我認爲你是對的,所以我會接受它。謝謝! – ycsun

+0

是的,這只是爲我解決了同樣的問題,onItemLongClickListener不能從popupWindow中的ListView中調用。 –

0

我解決了這個問題,只需在convertview上設置OnClickListener,這是適配器的getView方法的參數。然後我調用listview的onItemClickListener的方法onItemClick

無需使popupWindow可調焦逸岸,只是用ListPopupWindow是更容易,因爲它裏面只有getView()適配器方法,我們要添加一些代碼幾行

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方法

@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; 
    } 
相關問題