当焦点改变时,防止Spinner下拉消失

时间:2014-06-30 11:02:28

标签: android

我有一个下拉微调器,点击按钮时显示如下:

 <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();                
        }
    });       

我的微调器可以正确显示下拉弹出窗口。问题是我的布局有一个listview,它从后台的Web服务获取数据。当数据完全加载时,将显示或刷新所有列表项,并且微调器的下拉弹出窗口被忽略(我甚至不触摸屏幕上的任何内容)。
我认为问题是窗口已经改变了对其他观点的关注。那我怎么能阻止呢?

更新: 这是我从背景加载数据后的列表,它非常简单:

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);

2 个答案:

答案 0 :(得分: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,只要布局传递更改了屏幕中的视图,就会通知ListView。并且如果Spinner在发生后不可见,弹出窗口将被取消。加载Spinner显然会导致视图层次结构发生变化,并且当数据从服务器到达时会被触发。

对于一般用法,这是完全合乎逻辑的:如果isVisibleToUser()被隐藏,或者它离开了屏幕,或类似的东西,那么让弹出窗口消失是合理的。但是,它干扰了你正在尝试做的事情。如果你能以某种方式覆盖@hide会很好,但遗憾的是它被标记为Spinner,所以这是不可能的。

我可以建议一种解决方法,比如将Spinner设置为可见但非常小吗?喜欢,身高1px?我认为应该足以欺骗这种方法。

另一种选择,可能是一种更明智的选择,就是完全放弃Button并使用PopupMenu代替。您可以将其锚定到{{1}},动态加载它,并在按下按钮时显示它。视觉效果应该是相同的。

答案 1 :(得分: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"/>