在我的Android应用中,我有EditText
。关注EditText
时,会显示PopupWindow
,其中包含ListView
。当EditText
在屏幕上时,用户可以继续键入PopupWindow
,同时他/她应该能够点击ListView
上的项目以解除PopupWindow
1}}。 (根据点击的ListView
项目,除了忽略PopupWindow
之外,还应该发生其他事情,但这里无关紧要。)
问题是,虽然"继续打字"部分工作,"点击一个项目"部分没有,因为OnItemClickListener
的{{1}}永远不会被调用,我无法弄清楚原因。
这是我的ListView
:
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();
}
});
}
获得焦点时打开PopupWindow
,并在edtPhone
失去焦点时关闭PopupWindow
。然后我有:
edtPhone
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
可以很好地滚动,只是无法点击。
我知道this post但该解决方案并不适用于我的目的。如果我改变这一行:
ListView
以下内容:
popup = new PopupWindow(view, 400, 300, false);
popup = new PopupWindow(view, 400, 300, true);
变为焦点,PopupWindow
变得可点击,好吧,但我无法继续输入ListView
。事实上,如果活动中还有其他控件,则它们都无法访问,就像edtPhone
是&#34;模态&#34;。
我也试过PopupWindow
,没有运气。而且我没有自动完成,因此android:focusable="false"
并不是我需要的。
那么为什么AutoCompleteTextView
没有被调用到不可聚焦的OnItemClickListener
?我做错了吗?
答案 0 :(得分:1)
将弹出窗口设置为不可聚焦
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。
答案 1 :(得分:0)
我通过在OnClickListener
上设置convertview
解决了这个问题,这是适配器的getView
方法的参数。然后我调用listview的onItemClick
方法onItemClickListener。
无需使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);
MentionsAdapter
getView
方法
@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;
}