Question

I inflate a ListView inside a PopupWindow and I want the popup to behave like this:

  • wrap the listview when its height is < x
  • set the popup's height = x when the listiew's height > x (the listview being scrollable)

the popup is showed by a TextWatcher attached to an EditText, as it is meant to show search suggestions. The adapter underlying the ListView is managed by a custom Loader, started whenever the user has typed something in the EditText. I tried to override onMeasure() on the listview and pass the measured height to a listener which calls PopupWindow.update(), but this creates a loop since the latter would end up calling the first. With the following code, the popup wraps the contained ListView as wanted, but the height is not restricted to any value. I need a solution to restrict the height to a maximum value, let's say 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);
    }
};
Was it helpful?

Solution

I have found the solution by myself. For anyone who will ever stumble upon this problem, the answer is to override the method onMeasure() of the ListView like this:

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);               
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top