将PopupWindow设置为具有最大高度

时间:2014-02-22 15:20:15

标签: android android-popupwindow

我在PopupWindow中膨胀一个ListView,我希望弹出窗口的行为如下:

  • 在其高度为< X
  • 当listiew的高度>设置弹出窗口的高度= x x(列表视图可滚动)

弹出窗口由附加到EditText的TextWatcher显示,因为它用于显示搜索建议。 ListView底层的适配器由自定义Loader管理,只要用户在EditText中输入内容,就会启动。 我试图在列表视图上覆盖onMeasure()并将测量的高度传递给调用PopupWindow.update()的侦听器,但这会创建一个循环,因为后者最终会调用第一个循环。 使用以下代码,弹出窗口会根据需要包装所包含的ListView,但高度不限于任何值。我需要一个解决方案来将高度限制为最大值,比方说300dp。

etFiltro.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            /...
        }
        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            Log.i("loader","text changed");
            filtro = String.valueOf(charSequence);
            getSupportLoaderManager().restartLoader(0,null,loaderCallbacks);
            if (popupWindow.isShowing()) popupWindow.dismiss();
        }
        @Override
        public void afterTextChanged(Editable editable) {               
            popupWindow.showAsDropDown(etFiltro);
        }
    });

private LoaderManager.LoaderCallbacks<Cursor> loaderCallbacks = new LoaderManager.LoaderCallbacks<Cursor>() {

    MyListView suggestionList;
    SimpleCursorAdapter adapter;
    int mHeight;

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        SuggestionLoader loader = new SuggestionLoader(MainActivity.this, databaseConnector, filtro);
        loader.setUpdateThrottle(500);
        View view = ((LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.popup_window,null);
        suggestionList = (MyListView) view.findViewById(R.id.suggestionList);
        adapter = new SimpleCursorAdapter(MainActivity.this,android.R.layout.simple_list_item_1,null,
                new String[]{"note"},new int[]{android.R.id.text1},0);
        suggestionList.setAdapter(adapter);
        suggestionList.setEmptyView(view.findViewById(R.id.tvNoSuggestions));
        //ensure previous popup is dismissed
        if (popupWindow!=null) popupWindow.dismiss();
        popupWindow = new PopupWindow(view,etFiltro.getWidth(),0);
        popupWindow.setWindowLayoutMode(0,WindowManager.LayoutParams.WRAP_CONTENT);
        popupWindow.setAnimationStyle(0);//0 = no animation; -1 = default animation            
        Log.i("loader","onCreateLoader");
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        adapter.changeCursor(cursor);           
        Log.i("loader","onLoadFinished");

    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
        Log.i("loader", "onLoaderReset");
        adapter.changeCursor(null);
    }
};

1 个答案:

答案 0 :(得分:2)

我自己找到了解决方案。对于任何偶然发现此问题的人来说,答案是覆盖ListView的方法onMeasure(),如下所示:

public class MyListView extends ListView {

public MyListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public MyListView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyListView(Context context) {
    super(context);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    //set your custom height. AT_MOST means it can be as tall as needed,
    //up to the specified size.

    int height = MeasureSpec.makeMeasureSpec(300,MeasureSpec.AT_MOST);

    super.onMeasure(widthMeasureSpec,height);               
}
}