学而实习之 不亦乐乎

Android 去除 ListView 在 setFilterText() 之后出现黑色弹框

2023-07-11 20:47:52

在使用 ListView 实现好友通讯录时,遇到问题:当给 ListView 的适配器 BaseAdapter 实现 Filterable 接口之后,调用:

mList.setFilterText(s.toString());

方法之后,ListView会自动出现一个显示当前过滤文字的黑色悬浮框。ListView 没有暴露相关方法去除弹框,寻找发现 ListView 父类 AbsListView 中的相关控件: 

/**
  * Used with type filter window
  */
EditText mTextFilter;

相关代码 
AbsListView.java:

/**
  * Sets the initial value for the text filter.
  * @param filterText The text to use for the filter.
  *
  * @see #setTextFilterEnabled
  */
public void setFilterText(String filterText) {
    // TODO: Should we check for acceptFilter()?
    if (mTextFilterEnabled && !TextUtils.isEmpty(filterText)) {
        createTextFilter(false);
        // This is going to call our listener onTextChanged, but we might not
        // be ready to bring up a window yet
        mTextFilter.setText(filterText);
        mTextFilter.setSelection(filterText.length());
        if (mAdapter instanceof Filterable) {
            // if mPopup is non-null, then onTextChanged will do the filtering
            if (mPopup == null) {
                Filter f = ((Filterable) mAdapter).getFilter();
                f.filter(filterText);
            }
            // Set filtered to true so we will display the filter window when our main
            // window is ready
            mFiltered = true;
            mDataSetObserver.clearSavedState();
        }
    }
}


    
typing_filter.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:textSize="36dp"
    android:textColor="#99FFFFFF"
    android:background="#BB000000"
    android:minWidth="240dip"
    android:maxWidth="240dip"
    android:padding="10dip"
    android:gravity="center_horizontal"
    android:focusable="false"
/>

解决方法,通过反射设置 mTextFilter 属性达到隐藏弹框(或修改弹窗样式效果):

private void changeSearch(ListView listView) {
    try {
        Field field = listView.getClass().getSuperclass().getDeclaredField("mTextFilter");
        field.setAccessible(true);
        EditText searchAutoComplete = (EditText) field.get(listView);
        //searchAutoComplete.setTextColor(getResources().getColor(android.R.color.transparent));
      //searchAutoComplete.setBackgroundColor(getResources().getColor(android.R.color.transparent));
        searchAutoComplete.setVisibility(View.GONE);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

设置之后,黑色弹框成功隐藏。