【问题标题】:Setting PopupWindow to have a maximum height将 PopupWindow 设置为具有最大高度
【发布时间】:2014-02-22 15:20:15
【问题描述】:

我在 PopupWindow 中为 ListView 充气,我希望弹出窗口的行为如下:

  • 当高度为 时包裹列表视图
  • 当列表视图的高度 > x 时设置弹出窗口的高度 = x(列表视图可滚动)

弹出窗口由附加到 EditText 的 TextWatcher 显示,因为它旨在显示搜索建议。 ListView 底层的适配器由自定义加载器管理,只要用户在 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);
    }
};

【问题讨论】:

    标签: android android-popupwindow


    【解决方案1】:

    我自己找到了解决方案。对于任何会偶然发现此问题的人,答案是重写 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);               
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多