从另一个PopUp窗口显示一个PopUp窗口

时间:2014-08-12 07:52:05

标签: java android eclipse popupwindow android-context

我创建了一个具有两个AutoComplete EditText视图的PopupWindow的应用程序。 AutoCompletes有一个OnTextChangeListener,假设每次输入一个新字符时都会触发DropDown Popup Window并提供建议。但是,当我运行测试时,这是我得到的Logcat(仅错误)。

android.view.WindowManager$BadTokenException: Unable to add window -- token    android.view.ViewRoot$W@40aab400 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:450)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:283)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:193)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:118)
at android.view.Window$LocalWindowManager.addView(Window.java:532)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:943)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:855)
at android.widget.ListPopupWindow.show(ListPopupWindow.java:588)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1064)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:943)
at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:926)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4126)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)

我需要帮助,建议如何从弹出窗口显示DropDown弹出窗口。

Chris建议代码如下。

public class CustomAutoCompleteTextView extends AutoCompleteTextView {

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

/** Returns the place description corresponding to the selected item */
@Override
protected CharSequence convertSelectionToString(Object selectedItem) {
    /** Each item in the autocompetetextview suggestion list is a hashmap object */
    HashMap<String, String> hm = (HashMap<String, String>) selectedItem;
    return hm.get("description");
    }
}

这是我的CustomAutoComplete类

public void popupInit() {

    popupView = inflater.inflate(R.layout.poplayout, null);
    insidePopupButton.setOnClickListener(this);
    popUp = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
    popUp.setFocusable(true);
    popUp.setOutsideTouchable(isRestricted());
    test = (Button) findViewById(R.id.button1);



}

此函数初始化具有两个CustomAutoComplete的父弹出窗口。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.Searchview) {

        popUp.showAtLocation(getWindow().getDecorView(),Gravity.CENTER,0,0);
        popUp.isFocusable();
        popUp.setContentView(inflater.inflate(R.layout.poplayout, null, false));
        from = (AutoCompleteTextView) popupView.findViewById(R.id.origin_pl);
        to = (AutoCompleteTextView) popupView.findViewById(R.id.destination_pl);
        from.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count)   {
                placesTask = new PlacesTask();
                placesTask.execute(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
            }
        });

        to.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                placesTask = new PlacesTask();
                placesTask.execute(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
            }
        }); 
        return true;
    }
    else if (id == R.id.cancelview) {

        popUp.dismiss();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

这是创建一个menuItem的部分,比单击时,将显示主Popup窗口并为AutoCompleteTextViews设置OnTextXhangeListeners

private class PlacesTask extends AsyncTask<String, Void, String>{

    @Override
    protected String doInBackground(String... place) {
        // For storing data from web service
        String data = "";

        // Obtain browser key from https://code.google.com/apis/console
        String key = "key=Ajjljlljoojljlljljljllsg9A3doO6dfQ";

        String input="";

        try {
            input = "input=" + URLEncoder.encode(place[0], "utf-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }

        // place type to be searched
        String types = "types=geocode";

        // Sensor enabled
        String sensor = "sensor=false";

        // Building the parameters to the web service
        String parameters = input+"&"+types+"&"+sensor+"&"+key;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;

        try{
            // Fetching the data from we service
            data = downloadUrl(url);
        }catch(Exception e){
            Log.d("Background Task",e.toString());
        }
        return data;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        // Creating ParserTask
        parserTask = new ParserTaskJ();

        // Starting Parsing the JSON string returned by Web Service
        parserTask.execute(result);
    }
}
/** A class to parse the Google Places in JSON format */
private class ParserTaskJ extends AsyncTask<String, Integer, List<HashMap<String,String>>>{

    JSONObject jObject;

    @Override
    protected List<HashMap<String, String>> doInBackground(String... jsonData) {

        List<HashMap<String, String>> places = null;

        PlaceJSONParser placeJsonParser = new PlaceJSONParser();

        try{
            jObject = new JSONObject(jsonData[0]);

            // Getting the parsed data as a List construct
            places = placeJsonParser.parse(jObject);

        }catch(Exception e){
            Log.d("Exception",e.toString());
        }
        return places;
    }

    @Override
    protected void onPostExecute(List<HashMap<String, String>> result) {

        String[] from_in = new String[] { "description"};
        int[] to_in = new int[] { android.R.id.text1 };

        // Creating a SimpleAdapter for the AutoCompleteTextView
        SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from_in, to_in);

        // Setting the adapter
        if (from.hasFocus()) {
        from.setAdapter(adapter);
        }
        if (to.hasFocus()) {
            to.setAdapter(adapter);
        }
    }
}

这是我的AsyncTask,用于设置自动完成和网络活动。

我希望这一切都有道理。我在开头省略代码的原因是它的冗长。

谢谢。

1 个答案:

答案 0 :(得分:0)

对于将来可能遇到我的问题的人。我决定使用带有两个自动完成文本视图的AlertDialog。它更容易使用,受上下文和ViewGroups等的限制。