过滤自动完成适配器

时间:2015-12-13 01:35:40

标签: java android json google-places-api autocompletetextview

我的应用程序有一个自动完成适配器,我正在从Google Places API中获取json结果。我的麻烦在于试图让结果显示在屏幕上。我正在使用本指南:http://examples.javacodegeeks.com/android/android-google-places-autocomplete-api-example/

在大多数情况下,代码看似合理,但无论出于何种原因,我都无法将任何内容打印到显示器上。我真的不明白过滤器是如何工作的,也许对自动完成适配器如何工作的解释会有所帮助。

我的onCreate是:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        buildGoogleApiClient();
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        if (savedInstanceState != null) {
            mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING);
            mShouldResolve = savedInstanceState.getBoolean(KEY_SHOULD_RESOLVE);
        }

//      Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
                .setInterval(10 * 1000)           //10 seconds, in milliseconds
                .setFastestInterval(1 * 1000);   //1 second, in milliseconds

        Log.d(TAG, "GoogleApiClient built");

        if (savedInstanceState != null) {
            mSignInProgress = savedInstanceState
                    .getInt(SAVED_PROGRESS, STATE_DEFAULT);
        }

        mShouldResolve = true;
        mGoogleApiClient.connect();
        Log.d(TAG, "Starting sign-in");



        AutoCompleteTextView autoCompView = (AutoCompleteTextView)
                findViewById(R.id.autoCompleteTextView);


        autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.activity_maps));
        autoCompView.setOnItemClickListener(this);

    }

获取Json结果的方法是:

public ArrayList<String> autocomplete(String input) {
        Log.d(TAG, "performSearch()");

        ArrayList resultList = null;

        AsyncTask<ArrayList<String>, Void, ArrayList>
                myTask = new AsyncTask<ArrayList<String>, Void, ArrayList>() {

            AutoCompleteTextView text = (AutoCompleteTextView)
                    findViewById(R.id.autoCompleteTextView);
            private String input = text.getText().toString();

            @Override
            protected ArrayList doInBackground(ArrayList<String>... params) {
                Log.d(TAG, "Starting Search");

                ArrayList resultList = null;

                HttpURLConnection conn = null;
                StringBuilder jsonResults = new StringBuilder();
                try {
                    KEYWORD = input;

                    ENDPOINT = Uri
                            .parse("https://maps.googleapis.com/maps/api/place/nearbysearch/json")
                            .buildUpon()
                            .appendQueryParameter("location", LOCATION)
                            .appendQueryParameter("radius", "10000")
                            .appendQueryParameter("keyword", KEYWORD)
                            .appendQueryParameter("key", API_KEY)
                            .build();

                    URL url = new URL(ENDPOINT.toString());

                    Log.d(TAG, "URL: " + url);

                    conn = (HttpURLConnection) url.openConnection();
                    InputStreamReader in = new InputStreamReader(conn.getInputStream());

                    // Load the results into a StringBuilder
                    int read;
                    char[] buff = new char[1024];
                    while ((read = in.read(buff)) != -1) {
                        jsonResults.append(buff, 0, read);
                    }
                    Log.d(TAG, jsonResults.toString());
                } catch (MalformedURLException e) {
                    Log.e(TAG, "Error processing Places API URL", e);
                    return resultList;
                } catch (IOException e) {
                    Log.e(TAG, "Error connecting to Places API", e);
                    return resultList;
                } finally {
                    if (conn != null) {
                        conn.disconnect();
                    }
                }
                try {
                    // Create a JSON object hierarchy from the results
                    JSONObject jsonObj = new JSONObject(jsonResults.toString());
                    JSONArray predsJsonArray = jsonObj.getJSONArray("results");

                    // Extract the Place descriptions from the results
                    resultList = new ArrayList(predsJsonArray.length());
                    for (int i = 0; i < predsJsonArray.length(); i++) {
                        System.out.println(predsJsonArray.getJSONObject(i).getString("name"));
                        System.out.println(predsJsonArray.getJSONObject(i).getString("vicinity"));
                        System.out.println("=====================================================");
                        resultList.add(predsJsonArray.getJSONObject(i).getString("name"));
                        resultList.add(predsJsonArray.getJSONObject(i).getString("vicinity"));
                    }
                } catch (JSONException e) {
                    Log.e(TAG, "Cannot process JSON results", e);
                }
                Log.d(TAG, resultList.toString());
                return resultList;
            }

        };

        myTask.execute();

        Log.d(TAG, resultList.toString());
        return resultList;
    }

我的过滤器类是:

class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable {
        private ArrayList resultList;

        public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
        }

        @Override
        public int getCount() {
            return resultList.size();
        }

        @Override
        public String getItem(int index) {
            return (String) resultList.get(index);
        }

        @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
                    FilterResults filterResults = new FilterResults();
                    if (constraint != null) {
                        // Retrieve the autocomplete results.
                         resultList = autocomplete(constraint.toString());

                        // Assign the data to the FilterResults
                        filterResults.values = resultList;
                        filterResults.count = resultList.size();
                    }
                    return filterResults;
                }

                @Override
                protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
                    if (results != null && results.count > 0) {
                        notifyDataSetChanged();
                    } else {
                        notifyDataSetInvalidated();
                    }
                }
            };
            return filter;
        }
    }

我知道我从谷歌获得了良好的结果,我的内置阵列看起来像这样(包括名称和附近):

  

[Midtown Global Market,920 East Lake Street#G10,Minneapolis,The   Anchor Fish&amp;芯片,302 13th Avenue Northeast,Minneapolis,Brasa   Premium Rotisserie,600 East Hennepin Avenue,Minneapolis,Wedge   社区合作社,2105 Lyndale Avenue South,Minneapolis,Tao Natural   Foods,2200 Hennepin Avenue,Minneapolis,Fresh&amp;天然食品,1075   Highway 96 West,Saint Paul,Whole Foods Market,222 Hennepin Avenue,   明尼阿波利斯,Sen Yai Sen Lek Thai,2422 Central Avenue Northeast,   明尼阿波利斯,密西西比市场天然食品合作社,622塞尔比大道,   圣保罗,Eastside Food Co-Op,2551 Central Avenue Northeast,   明尼阿波利斯,明尼阿波利斯西湖街721号,进口食品,   Seoul Foods,1071 East Moore Lake Drive,Minneapolis,Seward Community   合作社 - 富兰克林商店,2823 East Franklin Avenue,Minneapolis,Foxy   Falafel,791 Raymond Avenue,Saint Paul,Asian Foods,1300 L'Orient   Street,Saint Paul,Pohl Distributing Co,510 Kasota Avenue Southeast,   明尼阿波利斯,Rainbow Foods,1566 University Avenue West,Saint Paul,   蒲公英厨房卡车,800 Nicollet购物中心,明尼阿波利斯,世界街   厨房,2743 Lyndale Avenue South#5,Minneapolis,CES Food Shelf,   明尼阿波利斯东19街]

感谢任何帮助,谢谢!

[编辑] 这是我的activity_maps的XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 xmlns:tools="http://schemas.android.com/tools"
                 android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context="com.hudsoncorp.zahudson.roadtrip.MapsActivity">

        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:map="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/map"
            tools:context="com.hudsoncorp.zahudson.roadtrip.MapsActivity"
            android:name="com.google.android.gms.maps.SupportMapFragment"/>

        <RelativeLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="10dp">

            <AutoCompleteTextView
                android:id="@+id/autoCompleteTextView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:hint="Search location"
                android:background="#FFFFFF"
                android:textColor="#00000F"
                      android:theme="@android:style/Widget.Material.AutoCompleteTextView"
                android:ems="10"
                android:shadowColor="@color/background_floating_material_dark">
                <requestFocus />

            </AutoCompleteTextView>

        </RelativeLayout>

</RelativeLayout>

1 个答案:

答案 0 :(得分:1)

我发现您有一个AsyncTask来从服务器访问您的数据,但您并不需要AsyncTask,因为performFiltering()已经在后台运行,所以你可以将doInBackground()逻辑放在performFiltering()

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                ArrayList<String> resultList = null;
                FilterResults filterResults = new FilterResults();

                if (constraint != null) {
                    // Retrieve the autocomplete results.
                    Log.d(TAG, "Starting Search");

                    HttpURLConnection conn = null;
                    StringBuilder jsonResults = new StringBuilder();
                    try {
                        KEYWORD = constraint.toString();

                        ENDPOINT = Uri
                                .parse("https://maps.googleapis.com/maps/api/place/nearbysearch/json")
                                .buildUpon()
                                .appendQueryParameter("location", LOCATION)
                                .appendQueryParameter("radius", "10000")
                                .appendQueryParameter("keyword", KEYWORD)
                                .appendQueryParameter("key", API_KEY)
                                .build();

                        URL url = new URL(ENDPOINT.toString());

                        Log.d(TAG, "URL: " + url);

                        conn = (HttpURLConnection) url.openConnection();
                        InputStreamReader in = new InputStreamReader(conn.getInputStream());

                        // Load the results into a StringBuilder
                        int read;
                        char[] buff = new char[1024];
                        while ((read = in.read(buff)) != -1) {
                            jsonResults.append(buff, 0, read);
                        }
                        Log.d(TAG, jsonResults.toString());
                    } catch (MalformedURLException e) {
                        Log.e(TAG, "Error processing Places API URL", e);
                        return filterResults ;
                    } catch (IOException e) {
                        Log.e(TAG, "Error connecting to Places API", e);
                        return filterResults ;
                    } finally {
                        if (conn != null) {
                            conn.disconnect();
                        }
                    }
                    try {
                        // Create a JSON object hierarchy from the results
                        JSONObject jsonObj = new JSONObject(jsonResults.toString());
                        JSONArray predsJsonArray = jsonObj.getJSONArray("results");

                        // Extract the Place descriptions from the results
                        resultList = new ArrayList(predsJsonArray.length());
                        for (int i = 0; i < predsJsonArray.length(); i++) {
                            System.out.println(predsJsonArray.getJSONObject(i).getString("name"));
                            System.out.println(predsJsonArray.getJSONObject(i).getString("vicinity"));
                            System.out.println("=====================================================");
                            resultList.add(predsJsonArray.getJSONObject(i).getString("name"));
                            resultList.add(predsJsonArray.getJSONObject(i).getString("vicinity"));
                        }
                    } catch (JSONException e) {
                        Log.e(TAG, "Cannot process JSON results", e);
                    }
                    Log.d(TAG, resultList.toString());

                    // Assign the data to the FilterResults
                    filterResults.values = resultList;
                    filterResults.count = resultList.size();
                }
                return filterResults;
            }

Filter就像AsyncTask一样。 performFilteringdoInBackground类似,publishResults()onPostExecute()类似。

顺便说一句,不要在后台线程中更新适配器列表。创建一个新列表并将其分配给FilterResults.values,然后在publishResults()中分配适配器列表。

publishResults()应如下所示:

            @Override
            protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
                if (results != null && results.count > 0) {
                    resultList = (ArrayList) results.values;
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }