Search code examples
androidlistviewandroid-adapterandroid-adapterview

when i try to add cardView as a container to TextView in ListView app Carshed?


enter image description here

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?


Solution

  • 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);