I want to make autoCompletePlace EditText with Custom ListView
1- xml
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<EditText
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="enter location"
android:id="@+id/edEnterLocation"
android:textColor="#000">
<requestFocus />
</EditText>
<ListView
android:layout_marginTop="100dp"
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</LinearLayout>
Second xml >> adapter_google_places_autocomplete
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/linearLayout"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_marginTop="6dp"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:cardCornerRadius="5dp"
app:cardMaxElevation="6dp"
app:cardElevation="6dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:textColor="#000"
android:textSize="18dp"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
xmlns:android="http://schemas.android.com/apk/res/android" />
</android.support.v7.widget.CardView>
</LinearLayout>
Java files 1-
package belalfci.googleapiplace1;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public ListView listView;
public EditText editText;
GooglePlacesAutocompleteAdapter dataAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout linearLayout=(LinearLayout)findViewById(R.id.linearLayout);
listView = (ListView) findViewById(R.id.listView1);
editText=(EditText) findViewById(R.id.edEnterLocation);
TextView txtView = (TextView)findViewById(R.id.textView);
CardView cardView=(CardView)findViewById(R.id.cardView);
dataAdapter = new GooglePlacesAutocompleteAdapter(getApplicationContext(),R.layout.adapter_google_places_autocomplete);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
editText.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.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selectedLocation = dataAdapter.getItem(position);
editText.setText(selectedLocation);
}
});
}
}
2-
package belalfci.googleapiplace1;
import android.content.Context;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
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 = "AIzaSyCS_bFUFXJ4ni3chIVI0EvFxk231Yau2Do";
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);
//to make suggestions for custom Country
// sb.append("&components=country:eg");
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"));
}
} 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) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
return filter;
}
}
when I use just TextView in the Second xml it worked well But I need to add card View as a container to this TextView?
If you are using an ArrayAdapter
and you have an edited layout (as you have), you should to use the constructor with the TextView
id.
You are calling the construtor with wrong arguments, so change all your implementation to this:
YourAdapter:
public GooglePlacesAutocompleteAdapter(Context context, int layoutId, int textViewResourceId) {
super(context, layout, textViewResourceId);
this.context = context;
}
YourActivity:
dataAdapter = new GooglePlacesAutocompleteAdapter(this, R.layout.adapter_google_places_autocomplete, R.id.textView);