当焦点改变时,防止Spinner下拉菜单关闭

4

我有一个下拉旋转器,当点击一个按钮时会显示出来,看起来像这样:

 <Button
    android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Spinner
        android:id="@+id/spinMenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:spinnerMode="dropdown"
        android:visibility="invisible" />


    <ListView
        android:id="@+id/lvWall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

这里是一个显示下拉弹出框的代码片段:
      findViewById(R.id.btn).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            spinMenu.performClick();                
        }
    });       

我的下拉菜单可以正常显示弹出式窗口。问题是我的布局有一个列表视图,它从后台获取数据。当数据完全加载时,所有列表项将被显示或刷新,此时下拉菜单的弹出式窗口会消失(即使我没有触摸屏幕)。我认为问题是窗口已经转向其他视图。那么我该如何防止这种情况发生?
更新:以下是我从后台加载数据后的列表,非常简单:
List<Feed> data = result; 
FeedAdapter adapter = new FeedAdapter (this, data);
ListView lvWall = (ListView)findViewById(R.id.lvWall);
lvWall.setAdapter(adapter);

并为微调器提供数据:

 List<String> list = getMenus();
 ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinMenu.setAdapter(dataAdapter);

你能发一下 performClick() 的代码吗?还有,在你的异步任务中,加载 ListView 内容的地方。 - krodmannix
你的旋转器是在隐藏还是你有意想要隐藏它?我不明白你的意思,请解释一下。 - Zare Ahmer
使用android:nextFocusDown="@+id/idyouwannafocus"和android:nextFocusUp="@+id/et2"属性来更改下一个焦点。 - Zare Ahmer
@ZareAhmer 我想防止下拉弹出菜单隐藏。我尝试了你的方法,但仍然不起作用。 - ductran
@kevinrmannix 我更新了我的问题。 - ductran
2个回答

4
如果我理解正确,您有一个Spinner视图,您将其设置为不可见,唯一的目的是显示弹出菜单,而不是Spinner视图本身。在这种情况下,问题可能与Spinner.java中的此片段相关,更确切地说是DropdownPopup.show()函数:
public void show(int textDirection, int textAlignment) {
    ...
    super.show();
    ...

    // Make sure we hide if our anchor goes away.
    // TODO: This might be appropriate to push all the way down to PopupWindow,
    // but it may have other side effects to investigate first. (Text editing handles, etc.)
    final ViewTreeObserver vto = getViewTreeObserver();
    if (vto != null) {
        final OnGlobalLayoutListener layoutListener = new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (!Spinner.this.isVisibleToUser()) {
                    dismiss();
                } else {
                    computeContentWidth();

                    ...

这是什么意思?基本上,Spinner设置了一个ViewTreeObserver,以便在布局更改屏幕中的视图时得到通知。如果此后Spinner不可见,则弹出窗口将被关闭。显然,加载ListView会导致视图层次结构发生变化,并且当数据从服务器到达时会触发它。
对于一般用途而言,这完全合理:如果Spinner被隐藏或离开屏幕,或者类似于这样的情况,让弹出窗口消失是合理的。但是,它会干扰您试图做的事情。如果您可以以某种方式覆盖isVisibleToUser(),那将是很好的,但不幸的是,它被标记为@hide,因此不可能实现。
我可以建议一种解决方法,例如将Spinner设置为可见但非常小吗?比如高度为1px?我相信这应该足以愚弄这个方法。
另一个选择,也可能是更明智的选择,是放弃Spinner并改用PopupMenu。您可以将其锚定到Button,动态加载它,并在按下按钮时显示它。视觉效果应该是相同的。

谢谢您的建议,我想使用自定义ListView的弹出窗口,并且它起作用了。还有一个问题要问您:您在哪里找到DropdownPopup.show()源代码?我尝试在GrepCode上阅读,但找不到它。 - ductran
@R4j 这是 Spinner.java 内部类。请参见 https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/Spinner.java,大约在第1120行附近。 - matiash

1
如果您认为问题是由于焦点的改变导致的。您可以用多种方式进行设置。
首先创建一个focuschangeListener,然后在onfocuschange事件中执行您想要的操作。
yourView.setOnFocusChangeListener(testListener);

@Override
      public void onFocusChange(View arg0,
              boolean isFocused) 
      {
          if(isFocused)
           {
              //do your work here
            }
           else
           {
           }
       }

第二种防止视图聚焦的方法是...
<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:focusable="true" android:focusableInTouchMode="true"
    android:layout_width="0px" android:layout_height="0px"/>

<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
     to prevent the dummy from receiving focus again -->
<AutoCompleteTextView android:id="@+id/autotext"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:nextFocusUp="@id/autotext" android:nextFocusLeft="@id/autotext"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接