1

I want to add search functionality to my android tracker app, so that a user can search for a particular place in the list view. My code has plotted all the details on the map and I just want to search for a particular place and get the info of the earthquake.

MainActivity.java

package com.vuvucall.maptest;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    SupportMapFragment mapFragment;
    GoogleMap googleMap;
    ArrayList<Item> mItems = new ArrayList<>();
    FrameLayout mapsLayout;
    Button loadDataButton;
    boolean listLoad = true;
    LinearLayoutManager linearLayoutManager;
    RecyclerView recycleView;
    ListDataAdapter listDataAdapter;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        linearLayoutManager = new LinearLayoutManager(context);


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mapsLayout = (FrameLayout) findViewById(R.id.mapsLayout);
        loadDataButton = (Button) findViewById(R.id.loadDataButton);
        recycleView = (RecyclerView) findViewById(R.id.recycleView);
        recycleView.setLayoutManager(linearLayoutManager);


        mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);


        loadDataButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (listLoad) {
                    listLoad = false;
                    mapsLayout.setVisibility(View.VISIBLE);
                    recycleView.setVisibility(View.GONE);
                    loadMapsData(mItems);
                    loadDataButton.setText(getString(R.string.show_list));

                } else {
                    listLoad = true;
                    mapsLayout.setVisibility(View.GONE);
                    recycleView.setVisibility(View.VISIBLE);
                    loadListData(mItems);
                    loadDataButton.setText(getString(R.string.show_maps));
                }

            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //  getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @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();
//
//        //noinspection SimplifiableIfStatement
//        if (id == R.id.action_settings) {
//            return true;
//        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        this.googleMap = googleMap;

        new ProcessInBackground().execute();


    }


    public class ProcessInBackground extends AsyncTask<Integer, Void, ArrayList<Item>> {
        ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

        Exception exception = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog.setMessage("Busy loading rss feed...please wait...");
            progressDialog.show();
        }

        @Override
        protected ArrayList<Item> doInBackground(Integer... params) {

            try {
                URL url = new URL("http://quakes.bgs.ac.uk/feeds/MhSeismology.xml");

                //creates new instance of PullParserFactory that can be used to create XML pull parsers
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                //Specifies whether the parser produced by this factory will provide support
                //for XML namespaces
                factory.setNamespaceAware(false);

                //creates a new instance of a XML pull parser using the currently configured
                //factory features
                XmlPullParser xpp = factory.newPullParser();

                // We will get the XML from an input stream
                xpp.setInput(getInputStream(url), "UTF_8");

                /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
                 * We should take into consideration that the rss feed name is also enclosed in a "<title>" tag.
                 * Every feed begins with these lines: "<channel><title>Feed_Name</title> etc."
                 * We should skip the "<title>" tag which is a child of "<channel>" tag,
                 * and take into consideration only the "<title>" tag which is a child of the "<item>" tag
                 *
                 * In order to achieve this, we will make use of a boolean variable called "insideItem".
                 */
                boolean insideItem = false;

                // Returns the type of current event: START_TAG, END_TAG, START_DOCUMENT, END_DOCUMENT etc..
                int eventType = xpp.getEventType(); //loop control variable

                Item item = null;
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    //if we are at a START_TAG (opening tag)
                    if (eventType == XmlPullParser.START_TAG) {
                        //if the tag is called "item"
                        if (xpp.getName().equalsIgnoreCase("item")) {
                            insideItem = true;
                            item = new Item();
                        }
                        //if the tag is called "title"
                        else if (xpp.getName().equalsIgnoreCase("title")) {
                            if (insideItem) {
                                // extract the text between <title> and </title>
                                item.setTitle(xpp.nextText());
                            }
                        }
                        //if the tag is called "link"
                        else if (xpp.getName().equalsIgnoreCase("link")) {
                            if (insideItem) {
                                // extract the text between <link> and </link>
                                item.setLink(xpp.nextText());
                            }
                        } else if (xpp.getName().equalsIgnoreCase("geo:lat")) {
                            if (insideItem) {
                                //extract the text between <geo:lat> and </geo:lat>
                                item.setLat(Double.valueOf(xpp.nextText()));
                            }
                        } else if (xpp.getName().equalsIgnoreCase("geo:long")) {
                            if (insideItem) {
                                //extract the text between <geo:lat> and </geo:lat>
                                item.setLon(Double.valueOf(xpp.nextText()));
                            }
                        }
                    }
                    //if we are at an END_TAG and the END_TAG is called "item"
                    else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")) {
                        insideItem = false;
                        mItems.add(item);
                    }

                    eventType = xpp.next(); //move to next element
                }

            } catch (MalformedURLException e) {
                exception = e;
            } catch (XmlPullParserException e) {
                exception = e;
            } catch (IOException e) {
                exception = e;
            }

            return mItems;
        }

        @Override
        protected void onPostExecute(ArrayList<Item> s) {
            super.onPostExecute(s);


            // ArrayAdapter<Item> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, mItems);
            // lvRss.setAdapter(adapter);

            progressDialog.dismiss();
            loadDataButton.setVisibility(View.VISIBLE);
            loadListData(s);
        }
    }

    public InputStream getInputStream(URL url) {
        try {
            //openConnection() returns instance that represents a connection to the remote object referred to by the URL
            //getInputStream() returns a stream that reads from the open connection
            return url.openConnection().getInputStream();
        } catch (IOException e) {
            return null;
        }
    }

    private void loadMapsData(ArrayList<Item> listData) {

        int i = 0;

        for (Item item : listData) {

            if (i % 5 == 0) {
                googleMap.addMarker(new MarkerOptions()
                        .position(new LatLng(item.getLat(), item.getLon()))
                        .title(item.getTitle())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
            } else if (i % 5 == 1) {
                googleMap.addMarker(new MarkerOptions()
                        .position(new LatLng(item.getLat(), item.getLon()))
                        .title(item.getTitle())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
            } else if (i % 5 == 2) {
                googleMap.addMarker(new MarkerOptions()
                        .position(new LatLng(item.getLat(), item.getLon()))
                        .title(item.getTitle())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
            } else if (i % 5 == 3) {
                googleMap.addMarker(new MarkerOptions()
                        .position(new LatLng(item.getLat(), item.getLon()))
                        .title(item.getTitle())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
            } else if (i % 5 == 4) {
                googleMap.addMarker(new MarkerOptions()
                        .position(new LatLng(item.getLat(), item.getLon()))
                        .title(item.getTitle())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_VIOLET)));
            }

            i++;



        }


        LatLngBounds.Builder builder = new LatLngBounds.Builder();

        //the include method will calculate the min and max bound.
        for (Item item : listData) {
            builder.include(new LatLng(item.getLat(), item.getLon()));
        }


        LatLngBounds bounds = builder.build();

        int width = getResources().getDisplayMetrics().widthPixels;
        int height = getResources().getDisplayMetrics().heightPixels;
        int padding = (int) (width * 0.10); // offset from edges of the map 10% of screen

        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);

        googleMap.animateCamera(cu);
    }

    private void loadListData(ArrayList<Item> listData) {
        listDataAdapter = new ListDataAdapter(context, listData);
        recycleView.setAdapter(listDataAdapter);
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:visibility="gone"
                android:layout_alignParentRight="true"
                android:text="@string/show_maps"
                android:id="@+id/loadDataButton"
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </RelativeLayout>

    </android.support.v7.widget.Toolbar>

    <include android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/toolbar" layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@android:drawable/ic_dialog_info" />

</RelativeLayout>

New Issues

errors

errors

more errors

3
  • Use SearchView Commented Mar 18, 2019 at 6:13
  • You can use CustomSearchableSpinner. Commented Mar 18, 2019 at 6:45
  • add ListDataAdapter class Commented Mar 18, 2019 at 8:51

1 Answer 1

0

There are too many ways to do this but i think this is the easiest way to do this...

first make an Edittext in your xml file then find it in your main activity by findViewbyid(); after that in your Main Activity add below lines.....

editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }
        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }
        @Override
        public void afterTextChanged(Editable editable)
        {
            filter(editable.toString());
        }
    }); 

Now the filter method....put this method in your activity class after closing of onCreate method...

private void filter(String text) {
ArrayList<String> filterdNames = new ArrayList<>();
for (String s : yourList) {
     if (s.toLowerCase().contains(text.toLowerCase())) {
        filterdNames.add(s);
    }
}
    final ArrayAdapter adap=new ArrayAdapter(this,android.R.layout.simple_list_item_1,filterdNames);
    lv.setAdapter(adap);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String text=adap.getItem(position).toString();
            int position=yourlist.indexOf(text); 
        }
    });

Please ask if you are getting any problem with this:

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks so much for the answer and code if you haven't guessed I am quite new to android....I got this far...can you show me where in the files I should put these methods I think I am putting them in the wrong place....thanks again...its nice to have people helping who don't judge......
yes offcourse wait for two minutes i will update my answer
thanks so much I did what you said and my code got very angry I've fixed some of it but any help would be great you've been so much help already...I will edit my original code with the errors thanks
hi I added some images showing the issues I know it must be something small like variables needing declared but I can't figure it out again thanks for the help
In the above code yourlist means your arraylist in which you want to add search functionality and the others errors because you don't put your code in correct manner check the Opening and closing of methods and please upmark if you find your answer in this code
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.