与 Uber 一样,在 ListView 中显示带有 Google Places 的 AutoCompleteTextView

     2023-04-18     186

关键词:

【中文标题】与 Uber 一样,在 ListView 中显示带有 Google Places 的 AutoCompleteTextView【英文标题】:AutoCompleteTextView with Google Places shown in ListView just like Uber 【发布时间】:2015-08-01 18:19:37 【问题描述】:

我需要制作与此类似的屏幕。我认为它有 autocompletetextview 和 listview 来显示返回的结果。此处使用 Google Place API 自动建议地点,并相应更新列表视图适配器。 请任何形式的帮助表示赞赏。 提前致谢。

也检查了 AutoComplete 上的 android 示例项目的位置。但它没有任何列表视图来显示结果。相反,它会在 autocompletetextview 微调器中显示结果。我们可以对该项目进行的任何修改

Link to google sample project

【问题讨论】:

试试这个链接wptrafficanalyzer.in/blog/… 也发布您的代码以展示您的努力 @AnjaliTripathi 也检查了这个链接。他们都运作良好。但是你可以看到他们的下拉菜单来显示结果。我需要像屏幕截图一样在列表视图中显示它。谢谢 @RahulSood 如果符合您的要求,请接受答案。 【参考方案1】:

您完全可以通过使用EditTextListView 而不是AutoCompleteTextView 来实现这一点。在EditText 中输入字符,在此基础上通过调用GooglePlacesAutomplete 网络服务过滤ListView 中的结果。以下是代码:

这是您的布局文件(EditTextListView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:background="#ffffff"
tools:context="com.example.siddarthshikhar.liftsharesample.EnterLocationActivity">

    <EditText
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:layout_
        android:layout_
        android:textColorHint="#ffffff"
        android:id="@+id/edEnterLocation"
        android:textColor="#ffffff"
        android:textSize="@dimen/abc_text_size_medium_material"
        android:layout_alignParentLeft="true"
        android:backgroundTint="#00000000"
        android:gravity="start|center">
        <requestFocus />
    </EditText>

<ListView android:id="@+id/listView1" android:layout_
    android:layout_
    android:layout_below="@+id/filterLayout"/>

</RelativeLayout>

在您相应的 Activity 中,访问此 EditText 并应用 Filterable。为此,您必须使用 GooglePlacesAutompleteAdapter

以下是GooglePlacesAutompleteAdapter

public class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable 
private static final String LOG_TAG = "Google Places Autocomplete";
private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
private static final String OUT_JSON = "/json";
private static final String API_KEY = "your_api_key";
private ArrayList<String> resultList;
private Context context = null;
public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) 
    super(context, textViewResourceId);
    this.context = context;



@Override
public int getCount() 
    if(resultList != null)
        return resultList.size();
    else
        return 0;


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



public ArrayList<String> autocomplete(String input) 
    ArrayList<String> resultList = null;
    ArrayList<String> descriptionList = null;
    HttpURLConnection conn = null;
    StringBuilder jsonResults = new StringBuilder();
    try 
        StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
        sb.append("?key=" + API_KEY);
        sb.append("&components=country:in");
        sb.append("&input=" + URLEncoder.encode(input, "utf8"));

        URL url = new URL(sb.toString());
        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);
        
     catch (MalformedURLException e) 
        Log.e(LOG_TAG, "Error processing Places API URL", e);
        return resultList;
     catch (IOException e) 
        Log.e(LOG_TAG, "Error connecting to Places API", e);
        return resultList;
     finally 
        if (conn != null) 
            conn.disconnect();
        
    

    try 
        // Create a JSON object hierarchy from the results
        Log.d("yo",jsonResults.toString());
        JSONObject jsonObj = new JSONObject(jsonResults.toString());
        JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");

        // Extract the Place descriptions from the results
        resultList = new ArrayList(predsJsonArray.length());
        descriptionList = new ArrayList(predsJsonArray.length());
        for (int i = 0; i < predsJsonArray.length(); i++) 
            resultList.add(predsJsonArray.getJSONObject(i).toString());
            descriptionList.add(predsJsonArray.getJSONObject(i).getString("description"));
        
        saveArray(resultList.toArray(new String[resultList.size()]), "predictionsArray", getContext());
     catch (JSONException e) 
        Log.e(LOG_TAG, "Cannot process JSON results", e);
    

    return descriptionList;



@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, FilterResults results) 
            if (results != null && results.count > 0) 
                setImageVisibility();
                notifyDataSetChanged();
             else 
                notifyDataSetInvalidated();
            
        
    ;
    return filter;


访问适配器并将getFilter()应用于对应Activity中的EditText。在你之前创建的布局对应的 Activity 中添加以下内容:

dataAdapter = new   GooglePlacesAutocompleteAdapter(EnterLocationActivity.this, R.layout.adapter_google_places_autocomplete)

listView = (ListView) findViewById(R.id.listView1);
    // Assign adapter to ListView
    listView.setAdapter(dataAdapter);

    //enables filtering for the contents of the given ListView
    listView.setTextFilterEnabled(true);

etEnterLocation.addTextChangedListener(new TextWatcher() 

        public void afterTextChanged(Editable s) 
        

        public void beforeTextChanged(CharSequence s, int start, int count, int after) 
        

        public void onTextChanged(CharSequence s, int start, int before, int count) 

            dataAdapter.getFilter().filter(s.toString());
        
    );

这应该会让你继续前进。您可以根据需要修改布局。这基本上会在ListView 中加载自动完成数据。

【讨论】:

我喜欢你的方法,但是 'saveArray' 有什么作用呢? @SteveKamau 嗨。这与这个答案无关。我正在使用“saveArray”存储我进入 SharedPref 的列表。感谢您的支持!【参考方案2】:

Here 是如何做到这一点的一个例子。

您可以从适配器获得任何AutocompletePrediction。例如,只需从AutoCompleteTextViewAdapterView.OnItemClickListener 中调用getItem(int position),然后根据需要使用点击预测中的任何数据。

链接相关代码:

/**
 * Adapter that handles Autocomplete requests from the Places Geo Data API.
 * @link AutocompletePrediction results from the API are frozen and stored directly in this
 * adapter. (See @link AutocompletePrediction#freeze().)
 * <p>
 * Note that this adapter requires a valid @link com.google.android.gms.common.api.GoogleApiClient.
 * The API client must be maintained in the encapsulating Activity, including all lifecycle and
 * connection states. The API client must be connected with the @link Places#GEO_DATA_API API.
 */
public class PlaceAutocompleteAdapter
        extends ArrayAdapter<AutocompletePrediction> implements Filterable 

    private static final String TAG = "PlaceAutocompleteAdapter";
    private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
    /**
     * Current results returned by this adapter.
     */
    private ArrayList<AutocompletePrediction> mResultList;

    /**
     * Handles autocomplete requests.
     */
    private GoogleApiClient mGoogleApiClient;

    /**
     * The bounds used for Places Geo Data autocomplete API requests.
     */
    private LatLngBounds mBounds;

    /**
     * The autocomplete filter used to restrict queries to a specific set of place types.
     */
    private AutocompleteFilter mPlaceFilter;

    /**
     * Initializes with a resource for text rows and autocomplete query bounds.
     *
     * @see android.widget.ArrayAdapter#ArrayAdapter(android.content.Context, int)
     */
    public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
            LatLngBounds bounds, AutocompleteFilter filter) 
        //change the layout nex for your own if you'd like
        super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
        mGoogleApiClient = googleApiClient;
        mBounds = bounds;
        mPlaceFilter = filter;
    

    /**
     * Sets the bounds for all subsequent queries.
     */
    public void setBounds(LatLngBounds bounds) 
        mBounds = bounds;
    

    /**
     * Returns the number of results received in the last autocomplete query.
     */
    @Override
    public int getCount() 
        return mResultList.size();
    

    /**
     * Returns an item from the last autocomplete query.
     */
    @Override
    public AutocompletePrediction getItem(int position) 
        return mResultList.get(position);
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View row = super.getView(position, convertView, parent);

        // Sets the primary and secondary text for a row.
        // Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
        // styling based on the given CharacterStyle.

        AutocompletePrediction item = getItem(position);

        TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
        TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
        textView1.setText(item.getPrimaryText(STYLE_BOLD));
        textView2.setText(item.getSecondaryText(STYLE_BOLD));

        return row;
    

    /**
     * Returns the filter for the current set of autocomplete results.
     */
    @Override
    public Filter getFilter() 
        return new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence constraint) 
                FilterResults results = new FilterResults();

                // We need a separate list to store the results, since
                // this is run asynchronously.
                ArrayList<AutocompletePrediction> filterData = new ArrayList<>();

                // Skip the autocomplete query if no constraints are given.
                if (constraint != null) 
                    // Query the autocomplete API for the (constraint) search string.
                    filterData = getAutocomplete(constraint);
                

                results.values = filterData;
                if (filterData != null) 
                    results.count = filterData.size();
                 else 
                    results.count = 0;
                

                return results;
            

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) 

                if (results != null && results.count > 0) 
                    // The API returned at least one result, update the data.
                    mResultList = (ArrayList<AutocompletePrediction>) results.values;
                    notifyDataSetChanged();
                 else 
                    // The API did not return any results, invalidate the data set.
                    notifyDataSetInvalidated();
                
            

            @Override
            public CharSequence convertResultToString(Object resultValue) 
                // Override this method to display a readable result in the AutocompleteTextView
                // when clicked.
                if (resultValue instanceof AutocompletePrediction) 
                    return ((AutocompletePrediction) resultValue).getFullText(null);
                 else 
                    return super.convertResultToString(resultValue);
                
            
        ;
    

    /**
     * Submits an autocomplete query to the Places Geo Data Autocomplete API.
     * Results are returned as frozen AutocompletePrediction objects, ready to be cached.
     * objects to store the Place ID and description that the API returns.
     * Returns an empty list if no results were found.
     * Returns null if the API client is not available or the query did not complete
     * successfully.
     * This method MUST be called off the main UI thread, as it will block until data is returned
     * from the API, which may include a network request.
     *
     * @param constraint Autocomplete query string
     * @return Results from the autocomplete API or null if the query was not successful.
     * @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
     * @see AutocompletePrediction#freeze()
     */
    private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) 
        if (mGoogleApiClient.isConnected()) 
            Log.i(TAG, "Starting autocomplete query for: " + constraint);

            // Submit the query to the autocomplete API and retrieve a PendingResult that will
            // contain the results when the query completes.
            PendingResult<AutocompletePredictionBuffer> results =
                    Places.GeoDataApi
                            .getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
                                    mBounds, mPlaceFilter);

            // This method should have been called off the main UI thread. Block and wait for at most 60s
            // for a result from the API.
            AutocompletePredictionBuffer autocompletePredictions = results
                    .await(60, TimeUnit.SECONDS);

            // Confirm that the query completed successfully, otherwise return null
            final Status status = autocompletePredictions.getStatus();
            if (!status.isSuccess()) 
                Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
                        Toast.LENGTH_SHORT).show();
                Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
                autocompletePredictions.release();
                return null;
            

            Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
                    + " predictions.");

            // Freeze the results immutable representation that can be stored safely.
            return DataBufferUtils.freezeAndClose(autocompletePredictions);
        
        Log.e(TAG, "Google API client is not connected for autocomplete query.");
        return null;
    

【讨论】:

【参考方案3】:

您可以通过将以下代码添加到布局中以更简单的方式实现自动完成文本视图

<fragment
     android:id="@+id/place_autocomplete_fragment"
     android:layout_
     android:layout_
android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
/>

要使用上述代码,您需要在 Google 开发者控制台中为您的应用程序配置一些设置。完整示例请参考 Android Places autocomplete example

【讨论】:

android - 像 uber 应用一样的底页

】android-像uber应用一样的底页【英文标题】:android-Bottomsheetlikeuberapp【发布时间】:2017-12-0910:17:20【问题描述】:我正在研究底部工作表,我根据link的教程构建了类似的东西。我想知道如何将类似于Uber应用程序的功能组合在一... 查看详情

制作带复选框的listview控件

实现效果:  知识运用   ListView控件的GridLines  //设置是否在ListView控件中显示网格线  publicboolGridLinesget;set  和CheckBoxes属性  //设置listView控件中各数据项是否显示复选框  publicboolCheckBoxesget;set  以及ListView... 查看详情

C# ListView 设计

】C#ListView设计【英文标题】:C#ListViewDesign[closed]【发布时间】:2020-11-0406:50:20【问题描述】:我想制作使用NewsApi获取新闻的程序,并想在程序中显示它们,但我无法按我的意愿显示它们。我可以像第一张图片一样显示结果。Firs... 查看详情

如何在滚动 ListView 上显示类似 Whatsapp 的日期

】如何在滚动ListView上显示类似Whatsapp的日期【英文标题】:HowtodisplayadatelikeWhatsapponscrollingListView【发布时间】:2017-01-1618:02:36【问题描述】:当我像在WhatsApp中一样滚动ListView时,如何在应用中显示日期?为了清楚起见,请参见... 查看详情

SQLite 行 ID 与 ListView 行 ID 不匹配

】SQLite行ID与ListView行ID不匹配【英文标题】:SQLiterowIDsdonotmatchtheListViewrowIDs【发布时间】:2016-10-1407:15:17【问题描述】:我有一个SQLite数据库和一个ListView显示在主要活动中。在ListView中,我显示每个列表编号的详细信息,按下... 查看详情

创建带“_”的表与创建不带“_”的表一样吗?

】创建带“_”的表与创建不带“_”的表一样吗?【英文标题】:Iscreatingatablewitha"_"thesamethingascreatingatablewithouta"_"?【发布时间】:2021-08-0722:16:06【问题描述】:我习惯在SQL中这样创建表:StringcreateItems="CREATETABLEitem... 查看详情

如何在listview中使用jquery动态显示列表分隔符?

】如何在listview中使用jquery动态显示列表分隔符?【英文标题】:Howtodisplaythelistdividersdynamicallyusingjqueryinlistview?【发布时间】:2013-08-1309:27:19【问题描述】:我正在动态使用data-role="list-divider"在列表视图中显示类别数据。... 查看详情

iOS 实时位置跟踪器就像在 uber 中一样?

】iOS实时位置跟踪器就像在uber中一样?【英文标题】:iOSrealtimelocationtrackerlikeinuber?【发布时间】:2017-05-2407:21:37【问题描述】:我正在构建一个需要访问两个用户位置的iOS应用:司机和乘客。这个应用程序将与优步应用程序非... 查看详情

为啥我的 Listview 没有在我的活动中显示任何内容?

】为啥我的Listview没有在我的活动中显示任何内容?【英文标题】:WhyismyListviewnotshowinganythingonmyactivity?为什么我的Listview没有在我的活动中显示任何内容?【发布时间】:2019-11-2318:15:27【问题描述】:我创建了一个自定义列表,... 查看详情

如何在颤动中使我的文本与 listview.builder 一起滚动

】如何在颤动中使我的文本与listview.builder一起滚动【英文标题】:Howtomakemytextscrollablewithalongwithlistview.builderinflutter【发布时间】:2020-09-2922:03:11【问题描述】:所以,我有2个功能。一个是在顶部显示一些文本,另一个是listview.b... 查看详情

WPF XAML 在 ListView 中看不到复选框

】WPFXAML在ListView中看不到复选框【英文标题】:WPFXAMLcannotseecheckboxesinListView【发布时间】:2019-03-0403:15:06【问题描述】:我正在开发一个小型WPF项目,现在它包含一个窗口,该窗口应显示与列表中的许多值一样多的复选框。出于... 查看详情

c# Listview 成行显示

】c#Listview成行显示【英文标题】:c#Listviewdisplayinginlines【发布时间】:2010-04-2708:37:51【问题描述】:基本上,我有一个Listview控件,它具有列(以详细信息模式显示)我向其中添加了我想要显示的项目,每个项目都在1个列下(... 查看详情

在c#中,在imagelist中,如何按比例显示缩略图

在C#中在listview中,利用ImageList,按原图像比例显示缩略图(因为图像有时是横放的,有时是竖放的,显示出来有的正常,有的很怪)参考技术A首先选择listview的视图,然耨imagelist中的图片大小也必须是一样的,这样从listview中显示... 查看详情

像 Swift 中的 Uber iOS 应用程序一样在 Google Map 上移动注释?

】像Swift中的UberiOS应用程序一样在GoogleMap上移动注释?【英文标题】:MovetheannotationonGoogleMaplikeUberiOSapplicationinSwift?【发布时间】:2017-05-0406:34:22【问题描述】:我正在尝试开发一个基于Uber和Ola之类概念的应用程序。因此,为此... 查看详情

ListView 上的 LongPress 与 Android 上的超链接

】ListView上的LongPress与Android上的超链接【英文标题】:LongPressonListViewwithhyperlinkonAndroid【发布时间】:2014-06-2423:22:02【问题描述】:我正在Android中开发一个将ListView元素显示为片段的应用程序。我想在上下文菜单上放置一个超链... 查看详情

如何从数组中填充 ListView?

】如何从数组中填充ListView?【英文标题】:HowtopopulateListViewfromanArray?【发布时间】:2015-09-1415:34:39【问题描述】:我对安卓很陌生。我需要填充一个ListView。就像现在一样,我只是添加到一个数组中,然后尝试填充视图。它最... 查看详情

在 ListView 中显示文件列表

】在ListView中显示文件列表【英文标题】:ShowingalistoffilesinaListView【发布时间】:2012-03-0805:12:51【问题描述】:我想知道如何在ListView中显示目录中的文件。这些文件可以列出:Filedir=newFile(dirPath);File[]filelist=dir.listFiles();并通过Arr... 查看详情

如何在 Android 的 ListView 中延迟加载图像

】如何在Android的ListView中延迟加载图像【英文标题】:HowtolazyloadimagesinListViewinAndroid【发布时间】:2010-10-0705:13:54【问题描述】:我正在使用ListView来显示一些图像以及与这些图像相关联的标题。我正在从互联网上获取图像。有... 查看详情