Jason Wang
Jason Wang

Reputation: 53

Android search functionality using listview from JSON file(Hard )

1.My search functionality works fine using edittext,but for example if I type "1" than delete it the listview shows null,how can I make listview shows JSON again after I type something then delete it?

2.If I change to search COUNTRY rather than RANK ,I need to type full character like "INDIA" how can I just type "in" then it can appear INDIA? thanks

MainActivity.java

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.ListView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends Activity {
    // Declare Variables
    JSONObject jsonobject;
    JSONArray jsonarray;
    ListView listview;
    ListViewAdapter adapter;
    ProgressDialog mProgressDialog;
    ArrayList<HashMap<String, String>> arraylist;
    static String RANK = "rank";
    static String COUNTRY = "country";
    static String POPULATION = "population";
    static String URL="url";
    static String FLAG = "flag";
    EditText mEditText;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Get the view from listview_main.xml
        setContentView(R.layout.listview_main);
        // Execute DownloadJSON AsyncTask
        new DownloadJSON().execute();




        mEditText = (EditText) findViewById(R.id.inputSearch);
        mEditText.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) {

                    ArrayList<HashMap<String, String>> arrayTemplist = new ArrayList<HashMap<String, String>>();
                    String searchString = mEditText.getText().toString();
                    for (int i = 0; i < arraylist.size(); i++) {
                        String currentString = arraylist.get(i).get(MainActivity.RANK);
                        if (searchString.equalsIgnoreCase(currentString)) {
                            arrayTemplist.add(arraylist.get(i));
                        }

                    }
                    adapter = new ListViewAdapter(MainActivity.this, arrayTemplist);
                    listview.setAdapter(adapter);

            }


        });
    }


    // DownloadJSON AsyncTask
    private class DownloadJSON extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Create a progressdialog
            mProgressDialog = new ProgressDialog(MainActivity.this);
            // Set progressdialog title
            mProgressDialog.setTitle("Android JSON Parse Tutorial");
            // Set progressdialog message
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            // Show progressdialog
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            arraylist = new ArrayList<HashMap<String, String>>();
            // Retrieve JSON Objects from the given URL address
            jsonobject = JSONfunctions
                    .getJSONfromURL("http://ndublog.twomini.com/123.txt.txt");

            try {
                // Locate the array name in JSON
                jsonarray = jsonobject.getJSONArray("worldpopulation");

                for (int i = 0; i < jsonarray.length(); i++) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    jsonobject = jsonarray.getJSONObject(i);
                    // Retrive JSON Objects
                    map.put("rank", jsonobject.getString("rank"));
                    map.put("country", jsonobject.getString("country"));
                    map.put("population", jsonobject.getString("population"));
                    map.put("url",jsonobject.getString("url"));
                    map.put("flag", jsonobject.getString("flag"));
                    // Set the JSON Objects into the array
                    arraylist.add(map);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            // Locate the listview in listview_main.xml
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new ListViewAdapter(MainActivity.this, arraylist);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);
            // Close the progressdialog
            mProgressDialog.dismiss();
        }
    }



        }

ListViewAdapter.java

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;

public class ListViewAdapter  extends BaseAdapter  {

    Context context;
    LayoutInflater inflater;
    public ArrayList<HashMap<String, String>> data;
    ImageLoader imageLoader;
    HashMap<String, String> resultp = new HashMap<String, String>();

    public ListViewAdapter(Context context,
            ArrayList<HashMap<String, String>> arraylist) {
        this.context = context;
        data = arraylist;
        imageLoader = new ImageLoader(context);
    }




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

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        // Declare Variables
        TextView rank;
        TextView country;
        TextView population;
        TextView url;
        ImageView flag;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.listview_item, parent, false);
        // Get the position
        resultp = data.get(position);

        // Locate the TextViews in listview_item.xml
        rank = (TextView) itemView.findViewById(R.id.rank);
        country = (TextView) itemView.findViewById(R.id.country);
        population = (TextView) itemView.findViewById(R.id.population);
        url=(TextView)itemView.findViewById(R.id.url);
        // Locate the ImageView in listview_item.xml
        flag = (ImageView) itemView.findViewById(R.id.flag);

        // Capture position and set results to the TextViews
        rank.setText(resultp.get(MainActivity.RANK));
        country.setText(resultp.get(MainActivity.COUNTRY));
        population.setText(resultp.get(MainActivity.POPULATION));
        url.setText(resultp.get(MainActivity.URL));
        // Capture position and set results to the ImageView
        // Passes flag images URL into ImageLoader.class
        imageLoader.DisplayImage(resultp.get(MainActivity.FLAG), flag);
        // Capture ListView item click
        itemView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // Get the position
                resultp = data.get(position);
                Intent intent = new Intent(context, SingleItemView.class);
                // Pass all data rank
                intent.putExtra("rank", resultp.get(MainActivity.RANK));
                // Pass all data country
                intent.putExtra("country", resultp.get(MainActivity.COUNTRY));
                // Pass all data population
                intent.putExtra("population",resultp.get(MainActivity.POPULATION));

                intent.putExtra("url",resultp.get(MainActivity.URL));
                // Pass all data flag

                intent.putExtra("flag", resultp.get(MainActivity.FLAG));
                // Start SingleItemView Class
                context.startActivity(intent);

            }
        });
        return itemView;

    }
}

Edit this code below,thanks

  import android.app.ListActivity;
    import android.app.ProgressDialog;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.Log;
    import android.widget.EditText;
    import android.widget.ListView;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    import java.util.ArrayList;
    import java.util.HashMap;


public class MainActivity extends ListActivity {
    // Declare Variables
    JSONObject jsonobject;
    JSONArray jsonarray;
    ListView listview;
    ListViewAdapter adapter;
    ProgressDialog mProgressDialog;
    ArrayList<HashMap<String, String>> arraylist;
    static String RANK = "rank";
    static String COUNTRY = "country";
    static String POPULATION = "population";
    static String URL="url";
    static String FLAG = "flag";
    EditText mEditText;
    String globalQuery="";
    ArrayList<HashMap<String, String>> globalList = new ArrayList<HashMap<String, String>>();
    ListViewAdapter globalListAdapter,globalAdapter=null;
    public void filteredList()
    {
//First of all checks for our globalList is not a null one.
        if(globalList!=null)
        {

            ArrayList<HashMap<String, String>> tempList = new ArrayList<HashMap<String, String>>();
//Checks our search term is empty or not.
            ListViewAdapter globalAdapter = null;
            if(!globalQuery.trim().equals(""))
            {
                boolean isThereAnyThing=false;
                for(int i=0;i<globalList.size();i++)
                {
//Get the value of globalList that is HashMap indexed at i.
                    HashMap<String, String> tempMap=globalList.get(i);
//Now getting all your HashMap values into local variables.
                    String rank=tempMap.get(MainActivity.RANK);
                    String country=tempMap.get(MainActivity.COUNTRY);
                    String population=tempMap.get(MainActivity.POPULATION);
                    String url=tempMap.get(MainActivity.URL);
                    String flag=tempMap.get(MainActivity.FLAG);
//Now all the core checking goes here for which one of these was typed like rank or country or population .....
                    if(rank.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || country.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || population.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || url.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || flag.regionMatches(true, 0, globalQuery,0, globalQuery.length()))
                    {
//If anything matches then it will add to tempList
                        tempList.add(tempMap);
                        isThereAnyThing=true;
                    }
                }
//Checks for is there anything matched from the ArrayList with the user type search query
                if(isThereAnyThing)
                {
//then set the globalAdapter with the new HashMaps tempList
                    globalAdapter = new ListViewAdapter(MainActivity.this, tempList);
                    listview.setAdapter(globalAdapter);
                    setListAdapter(globalAdapter);
                    ((ListViewAdapter)globalAdapter).notifyDataSetChanged();
                }
                else
                {
//If else set list adapter to null
                    setListAdapter(null);
                }
            }
            else
            {
                // Do something when there's no input
                if(globalAdapter==null)
                {
//If no user inputs then it will list everything in the globalList.
                    justListAll();
                }
                else
                {
                    final ListViewAdapter finalGlobalAdapter = globalAdapter;
                    runOnUiThread(new Runnable()
                    {
                        public void run()
                        {

                            ((ListViewAdapter) finalGlobalAdapter).notifyDataSetChanged();

                        }
                    });
                }

            }
            // updating listview

        }
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Get the view from listview_main.xml
        setContentView(R.layout.listview_main);
        // Execute DownloadJSON AsyncTask
        new DownloadJSON().execute();




        mEditText = (EditText) findViewById(R.id.inputSearch);

      mEditText.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {
                if (s.toString().length() > 0) {
                    // Search
                    globalQuery=s.toString();
//This method will filter all your categories just calling this method.
                    filteredList();
                } else {
                    globalQuery="";
//If the text is empty the list all the content of the list adapter
                    justListAll();
                }
            }

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

            }

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

                    ArrayList<HashMap<String, String>> arrayTemplist = new ArrayList<HashMap<String, String>>();
                    String searchString = mEditText.getText().toString();
                    if(searchString.equals("")){new DownloadJSON().execute();}

                else{


                for (int i = 0; i < arraylist.size(); i++) {
                    String currentString = arraylist.get(i).get(MainActivity.COUNTRY);
                    if (searchString.contains(currentString)) {
//pass the character-sequence instead of currentstring
                        arrayTemplist.add(arraylist.get(i));
                    }
                }
                    }
                    adapter = new ListViewAdapter(MainActivity.this, arrayTemplist);
                    listview.setAdapter(adapter);

            }


        });
    }


    // DownloadJSON AsyncTask
    private class DownloadJSON extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Create a progressdialog
            mProgressDialog = new ProgressDialog(MainActivity.this);
            // Set progressdialog title
            mProgressDialog.setTitle("Android JSON Parse Tutorial");
            // Set progressdialog message
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            // Show progressdialog
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            arraylist = new ArrayList<HashMap<String, String>>();
            // Retrieve JSON Objects from the given URL address
            jsonobject = JSONfunctions
                    .getJSONfromURL("http://ndublog.twomini.com/123.txt.txt");

            try {
                // Locate the array name in JSON
                jsonarray = jsonobject.getJSONArray("worldpopulation");

                for (int i = 0; i < jsonarray.length(); i++) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    jsonobject = jsonarray.getJSONObject(i);
                    // Retrive JSON Objects
                    map.put("rank", jsonobject.getString("rank"));
                    map.put("country", jsonobject.getString("country"));
                    map.put("population", jsonobject.getString("population"));
                    map.put("url",jsonobject.getString("url"));
                    map.put("flag", jsonobject.getString("flag"));
                    // Set the JSON Objects into the array
                    arraylist.add(map);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            // Locate the listview in listview_main.xml
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new ListViewAdapter(MainActivity.this, arraylist);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);
            // Close the progressdialog
            mProgressDialog.dismiss();
        }
    }


    public void justListAll()
    {
        ListViewAdapter globalAdapter = new ListViewAdapter(MainActivity.this, globalList);
        listview.setAdapter(adapter);
        setListAdapter(globalAdapter);
        ((ListViewAdapter)globalAdapter).notifyDataSetChanged();
    }

   }

Upvotes: 4

Views: 5920

Answers (3)

Angad Tiwari
Angad Tiwari

Reputation: 1768

do the following change to your edittext watcher... if the edittext.gettext().tostring().equals("") ...then just execute the asynctask

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

                ArrayList<HashMap<String, String>> arrayTemplist = new ArrayList<HashMap<String, String>>();
                String searchString = mEditText.getText().toString();
                if(searchString.equals(""))
                {
                    new DownloadJSON().execute();
                    //this will set you the whole json again to your listview
                }
                else
                {
                for (int i = 0; i < arraylist.size(); i++) {
                    String currentString = arraylist.get(i).get(MainActivity.RANK);
                    if (searchString.equalsIgnoreCase(currentString)) {
                        arrayTemplist.add(arraylist.get(i));
                    }

                }
                adapter = new ListViewAdapter(MainActivity.this, arrayTemplist);
                listview.setAdapter(adapter);
                }

        }

and in case of COUNTRY..why its behaving diff...it think you have to match the edittext substring with the arraylist

just replace the following code

if (searchString.equalsIgnoreCase(currentString)) {
                        arrayTemplist.add(arraylist.get(i));
                    }

with

if (searchString.contains(currentString)) {
//pass the character-sequence instead of currentstring
                        arrayTemplist.add(arraylist.get(i));
                    }

for COUNTRY search...

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

            ArrayList<HashMap<String, String>> arrayTemplist = new ArrayList<HashMap<String, String>>();
            String searchString = mEditText.getText().toString();
            if(searchString.equals(""))
            {
                new DownloadJSON().execute();
                //this will set you the whole json again to your listview
            }
            else
            {
            for (int i = 0; i < arraylist.size(); i++) {
                String currentString = arraylist.get(i).get(MainActivity.COUNTRY);
                if ( searchString .equalsIgnoreCase(currentString .substring(0,searchString .length()-1))) {
                    arrayTemplist.add(arraylist.get(i));
                }

            }
            adapter = new ListViewAdapter(MainActivity.this, arrayTemplist);
            listview.setAdapter(adapter);
            }

    }

Upvotes: 1

ShihabSoft
ShihabSoft

Reputation: 845

Thank you for asking the question in a good way as per the SO guidelines.

Iam sure this will solve your question.

//First of all declare a global variables
String globalQuery="";
ArrayList<HashMap<String, String>> globalList = new ArrayList<HashMap<String, String>>();
ListViewAdapter globalListAdapter;

public void afterTextChanged(Editable s) {
 if (s.toString().length() > 0) {
                    // Search
globalQuery=s.toString();
//This method will filter all your categories just calling this method.
filteredList();
                } else {
                    globalQuery="";
//If the text is empty the list all the content of the list adapter
                justListAll();
                }
            }

public void justListAll()
{
    globalAdapter = new ListViewAdapter(MainActivity.this, globalList);
                    listview.setAdapter(adapter);
    setListAdapter(globalAdapter);
    ((ListViewAdapter)globalAdapter).notifyDataSetChanged();
}

public void filteredList()
{
//First of all checks for our globalList is not a null one.
if(globalList!=null)
            {

    ArrayList<HashMap<String, String>> tempList = new ArrayList<HashMap<String, String>>();
//Checks our search term is empty or not.
    if(!globalQuery.trim().equals(""))
    {
        boolean isThereAnyThing=false;
    for(int i=0;i<globalList.size();i++)
    {
//Get the value of globalList that is HashMap indexed at i.
        HashMap<String, String> tempMap=globalList.get(i);
//Now getting all your HashMap values into local variables.
        String rank=tempMap.get(MainActivity.RANK);
        String country=tempMap.get(MainActivity.COUNTRY);
        String population=tempMap.get(MainActivity.POPULATION);
        String url=tempMap.get(MainActivity.URL);
        String flag=tempMap.get(MainActivity.FLAG);
//Now all the core checking goes here for which one of these was typed like rank or country or population .....
                if(rank.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || country.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || population.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || url.regionMatches(true, 0, globalQuery,0, globalQuery.length()) || flag.regionMatches(true, 0, globalQuery,0, globalQuery.length()))
                {
//If anything matches then it will add to tempList
                    tempList.add(tempMap);
                    isThereAnyThing=true;
                }
    }
//Checks for is there anything matched from the ArrayList with the user type search query
    if(isThereAnyThing)
    {
//then set the globalAdapter with the new HashMaps tempList
     globalAdapter = new ListViewAdapter(MainActivity.this, tempList);
                    listview.setAdapter(globalAdapter);
    setListAdapter(globalAdapter);
    ((ListViewAdapter)globalAdapter).notifyDataSetChanged();
    }
    else
    {
//If else set list adapter to null
        setListAdapter(null);
    }
}
else
{
    // Do something when there's no input
    if(globalAdapter==null)
    {
//If no user inputs then it will list everything in the globalList.
justListAll();
    }
    else
    {
         runOnUiThread(new Runnable()
         {
             public void run()
             {

    ((ListViewAdapter)globalAdapter).notifyDataSetChanged();

             }
         });
    }

         }
     // updating listview

            }
}

Only a thing you want to do is populate all the JSON parsed values to the global ArrayList globalList.

Hope it answers the whole question with extra packups.

Upvotes: 1

rf43
rf43

Reputation: 4405

  1. When you delete the character, the text in the EditText view is null therefore it is looking for null and the list displays null. Make sure you perform a null check before searching through your JSON array.
  2. It looks like you just need to change this line:

    String currentString = arraylist.get(i).get(MainActivity.RANK);

    to

    String currentString = arraylist.get(i).get(MainActivity.COUNTRY);

Upvotes: 1

Related Questions