Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42768

Using AutoCompleteTextView as Toolbar component will cause mystery crash when showing dropdown

Previously, before material design, I'm using AutoCompleteTextView as ActionBarSherlock's actionLayout.

AutoCompleteTextView as ActionBarSherlock's actionLayout (Workable)

menu.xml

<item 
    android:id="@+id/menu_search"
    android:title="@string/menu_search"
    app:showAsAction="always|collapseActionView"
    app:actionLayout="@layout/collapsible_searchtext"
    android:icon="?attr/actionBarSearchIcon"/>    

collapsible_searchtext.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center"
    >
    <org.yccheok.jstock.gui.JStockAutoCompleteTextView 
        android:id="@+id/search"
        android:dropDownWidth="match_parent"
        android:completionThreshold="1"
        android:inputType="textNoSuggestions"
        android:imeOptions="actionSearch|flagNoExtractUi"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:singleLine="true"
        android:hint="@string/search_stock"
        android:layout_gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_marginRight="15dip"
        android:layout_gravity="right|center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="invisible"
        style="?attr/editTextIndeterminateProgressStyle" />
</FrameLayout>

It works perfectly fine.

Currently, I try to migrate my app to material design. The first thing I was trying to do, is replacing ActionBarSherlock, with android.support.v7.widget.Toolbar

It works perfectly fine, till I try to show drop down. I get the following exception, while typing in some text, which should trigger drop down to be shown.

java.lang.NullPointerException
    at android.widget.PopupWindow.getMaxAvailableHeight(PopupWindow.java:1233)
    at android.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1098)
    at android.widget.ListPopupWindow.show(ListPopupWindow.java:532)
    at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1096)
    at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:971)
    at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:953)
    at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5103)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)

AutoCompleteTextView as Toolbar's component (Crash)

Toolbar.xml

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/background_material_dark"
    android:elevation="4dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >

    <view class="org.yccheok.jstock.gui.JStockSearchView"
        android:id="@+id/search_view"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:visibility="gone"/>

</android.support.v7.widget.Toolbar>

jstock_search_view.xml

<view class="org.yccheok.jstock.gui.JStockSearchView$JStockAutoCompleteTextView"
    android:id="@+id/search_src_text"
    android:layout_height="36dip"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:minWidth="@dimen/abc_search_view_text_min_width"
    android:layout_gravity="bottom"
    android:paddingLeft="@dimen/abc_dropdownitem_text_padding_left"
    android:paddingRight="@dimen/abc_dropdownitem_text_padding_right"
    android:singleLine="true"
    android:ellipsize="end"
    android:background="@null"
    android:hint="@string/search_stock"
    android:inputType="text|textAutoComplete|textNoSuggestions"
    android:imeOptions="actionSearch|flagNoExtractUi"
    android:dropDownHeight="wrap_content"
    android:dropDownAnchor="@id/search_edit_frame"
    android:dropDownVerticalOffset="0dip"
    android:dropDownHorizontalOffset="0dip" />
    ...

Note: My jstock_search_view.xml is mimic from official abc_search_view.xml found in AppCompat. Since AppCompat's doesn't suit my use case, I decide to have a customized version of SearchView.

My code of using AutoCompleteTextView is pretty straight forward. I don't get much hint, on what causes it went wrong.

public JStockSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.jstock_search_view, this, true);

    ...
    
    mSearchSrcTextView = (JStockAutoCompleteTextView) findViewById(R.id.search_src_text);

    mSearchSrcTextView.addTextChangedListener(mTextWatcher);

    // Sample data.
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_dropdown_item_1line, COUNTRIES);
    mSearchSrcTextView.setAdapter(adapter);
}

private static final String[] COUNTRIES = new String[] {
    "Belgium", "France", "Frances", "Italy", "Germany", "Spain"
};

To reproduce crash, we just need to type Fr, to trigger drop down.

I create a minimal workable code - https://github.com/yccheok/toolbar-experiment/tree/2d8853ab656b41837b004fd84060793f2b0b6ea6, to demonstrate such problem.

If you find out any hint why it doesn't work, I would be very much appreciated.

Upvotes: 0

Views: 1321

Answers (1)

Paul Burke
Paul Burke

Reputation: 25584

Follow the exception and it's completely clear what's happening: the "anchor" view is null. Simply adding this to your JStockSearchView constructor makes it work fine:

mSearchSrcTextView.setDropDownAnchor(R.id.search_plate);

You're setting the attribute android:dropDownAnchor in XML, but never actually reading it in the JStockSearchView. The better solution would probably be to get that attribute (rather than hard code the anchor id).

Upvotes: 1

Related Questions