Put JSON array data in Hashmap and pass it through Intent Extra - java

In my app, I have successfully implemented passing JSON Objects via Intent to a new activity by doing find "findviewByid."
Now this is a restaurant finder app, and each restaurant has several menu photos. I was looking all over stackoverflow to find sth like it but couldn't implement.
This is a part of my JSON file:
[
{
login_id: "6",
name: "Urban Spice",
location: "banani",
latitude: "23.790327",
longitude: "90.409007",
address: "House- 119, Road-11, Block-E, Banani",
rating: "4.00",
costfortwopeople: "0",
openingclosingtime: "",
type: "restaurant,ice cream parlour",
perks: "kids zone,home delivery,catering",
cuisine: "indian,indonesian",
phone: "01777899901,2,3,9862672",
image: - [
"http://www.petuuk.com/restaurant_images/img_2146.jpg",
"http://www.petuuk.com/restaurant_images/img_2147.jpg"
],
menu: - [
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg"
]
},
{
login_id: "7",
name: "The Sky Room Dining",
location: "banani",
latitude: "23.793972",
longitude: "90.403190",
address: "ABC House, 12th Floor, 8 Kemal Ataturk Avenue, Banani",
rating: "4.00",
costfortwopeople: "0",
openingclosingtime: "",
type: "restaurant",
perks: "rooftop view,catering",
cuisine: "thai,indian",
phone: "01675019211,9822017",
image: - [
"http://www.petuuk.com/restaurant_images/img_2204.jpg",
"http://www.petuuk.com/restaurant_images/img_2205.jpg",
"http://www.petuuk.com/restaurant_images/img_2206.jpg"
], etc..................................................................
I'm having a hard time retrieving the JSON array "menu" and "image" from the JSON output as above. I was able to retrieve the other JSON Objects such as login_id, name, location etc.
The main objective I am trying to achieve here is, load all the data in the Listview, where a user can search a restaurant, then when the user clicks on the specific restaurant, all the loaded data should gets into the "Intent.putExtra" for getting viewed in a full restaurant profile view in a new activity.
These are parts of my "SeachAll" activity where I need help. This is the for loop for retrieving data from the JSON file. I need help here retrieving data from "image" and "menu" and then putting it into my hashmap.
protected String doInBackground(String... arg) {
//building parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Getting JSON from URL
String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);
//Log Cat Response Check
Log.d("Areas JSON: ", "> " + json);
try {
restaurants = new JSONArray(json);
if (restaurants != null) {
//loop through all restaurants
for (int i = 0; i < restaurants.length(); i++) {
JSONObject c = restaurants.getJSONObject(i);
//Storing each json object in the variable.
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String location = c.getString(TAG_LOCATION);
String rating = c.getString(TAG_RATING);` HashMap<String, String> map = new HashMap<String, String>();
//adding each child node to Hashmap key
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_LOCATION, location);
map.put(TAG_RATING, rating);
//adding HashList to ArrayList
restaurant_list.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}`
This is my onItemClick. Need help in putting the arrays, I dont know if it is alright to pass json array just like json objects i did below.
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
String loginId = ((TextView) view.
findViewById(R.id.login_id)).
getText().toString();
String res_name = ((TextView) view.
findViewById(R.id.restaurant_name)).
getText().toString();
intent.putExtra(TAG_ID, loginId);
intent.putExtra(TAG_NAME, res_name);
startActivity(intent);
}
});
So In brief I need help with two things,
1. Retrieve JSON array "image" and "menu" URLS from the JSON file and put it inside the Hashmap.
2. Put this data to my Intent for being passed to a new activity.
This my full code for "SearchAll" activity.
public class SearchAll extends ListActivity {
ConnectionDetector cd;
AlertDialogManager alert = new AlertDialogManager();
//Progress Dialog
private ProgressDialog pDialog;
//make json parser Object
JSONParser jsonParser = new JSONParser();
ArrayList<HashMap<String, String>> restaurant_list;
//Restaurant Json array
JSONArray restaurants = null;
private static final String URL_RESTAURANT_LIST
= "http://www.petuuk.com/android/allRestaurantList2.php";
//all JSON Node Names
private static final String TAG_ID = "login_id";
private static final String TAG_NAME = "name";
private static final String TAG_LOCATION = "location";
private static final String TAG_LAT = "lattitude";
private static final String TAG_LONG = "longitude";
private static final String TAG_ADDRESS = "address";
private static final String TAG_COST_2 = "costfortwopeople";
private static final String TAG_TYPE = "type";
private static final String TAG_PERKS = "perks";
private static final String TAG_CUISINE = "cuisne";
private static final String TAG_PHONE = "phone";
private static final String TAG_RATING = "rating";
private static final String TAG_IMAGE = "image";
private static final String TAG_MENU = "menu";
private static final String TAG_TIMING = "openingclosingtime";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_all);
cd = new ConnectionDetector(getApplicationContext());
//Check for Internet Connection
if (!cd.isConnectingToInternet()) {
//Internet connection not present
alert.showAlertDialog(SearchAll.this, "Internet Connection Error",
"Please Check Your Internet Connection", false);
//stop executing code by return
return;
}
restaurant_list = new ArrayList<HashMap<String, String>>();
//get ListView
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
String loginId = ((TextView) view.
findViewById(R.id.login_id)).
getText().toString();
String res_name = ((TextView) view.
findViewById(R.id.restaurant_name)).
getText().toString();
intent.putExtra(TAG_ID, loginId);
intent.putExtra(TAG_NAME, res_name);
startActivity(intent);
}
});
lv.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
}
});
new LoadRestaurants().execute();
}
class LoadRestaurants extends AsyncTask<String, String, String> {
//Show Progress Dialog
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SearchAll.this);
pDialog.setMessage("Loading All Restaurants...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... arg) {
//building parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Getting JSON from URL
String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);
//Log Cat Response Check
Log.d("Areas JSON: ", "> " + json);
try {
restaurants = new JSONArray(json);
if (restaurants != null) {
//loop through all restaurants
for (int i = 0; i < restaurants.length(); i++) {
JSONObject c = restaurants.getJSONObject(i);
//Storing each json object in the variable.
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String location = c.getString(TAG_LOCATION);
String rating = c.getString(TAG_RATING);
String address = c.getString(TAG_ADDRESS);
String latitude = c.getString(TAG_LAT);
String longitude = c.getString(TAG_LONG);
String costfor2 = c.getString(TAG_COST_2);
String timing = c.getString(TAG_TIMING);
String type = c.getString(TAG_TYPE);
String perks = c.getString(TAG_PERKS);
String cuisine = c.getString(TAG_CUISINE);
String phone = c.getString(TAG_PHONE);
JSONArray menuArray = c.getJSONArray("menu");
JSONArray imagesArray = c.getJSONArray("image");
//Creating New Hashmap
HashMap<String, String> map = new HashMap<String, String>();
//adding each child node to Hashmap key
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_LOCATION, location);
map.put(TAG_RATING, rating);
for(int m=0;m<menuArray.length();++m){
map.put("MENU_" + m,menuArray.getString(m));
}//menu for loop
map.put("TOTAL_MENU", menuArray.length());
// map.put(TAG_MENU, String.valueOf(menu));
//adding HashList to ArrayList
restaurant_list.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
//dismiss the dialog
pDialog.dismiss();
//Updating UI from the Background Thread
runOnUiThread(new Runnable() {
#Override
public void run() {
ListAdapter adapter = new SimpleAdapter(
SearchAll.this, restaurant_list,
R.layout.listview_restaurants, new String[]{
TAG_ID, TAG_NAME, TAG_LOCATION, TAG_RATING}, new int[]{
R.id.login_id, R.id.restaurant_name, R.id.location, R.id.rating});
setListAdapter(adapter);
}
});
}
}
}

In short, you don't pass all of your data from one Activity to another. You should just pass a restaurant ID to a new Activity, and it uses that ID to pull data of the restaurant.
You should consider your restaurant list as (part of) Model in an MVC architecture. It should be separated from your Activities (which are Controller). Model is your data expert, it keeps your data in memory, files or a database, and it lives beyound the life-cycle of any particular Activity. You don't pass the Model from one Activity to another. After an Activity is created, it grabs the Model (if the Model is a Singleton) or the Model is injected into that Activity (Dependency Injection, my prefer framework is Dagger). The Activity then can ask for any particular data from the Model and render its View. It can also observe for any further changes within the Model and update its view accordlingly.

not sure of this is exactly what you need, but you might get some ideas out of this
first, to get the image and menu array, from the restaurant, you need this
inside the for loop, where you get the json object (c)
JSONObject c = restaurants.getJSONObject(i);
JsonArray menuArray = c.getJsonArray("menu");
JsonArray imagesArray = c.getJsonArray("image");
and you can loop among menuArray and imagesArray items using a for loop
imagesArray.getString(index);
now, as you have declared your map as < String, String > you can't assign a multiple values (images or menu items) in one string,
so either you find another way to structure your data,
or create another 2 maps, menuPam, imageMap that will have restaurant ID as key, and String as value for menu and image entries.
inside the for loop that read restaurant objects:
for (int i = 0; i < restaurants.length(); i++) {
:
:
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
:
:
JsonArray menuArray = c.getJsonArray("menu");
for(int m=0;m<menuArray.length();++m){
menuMap.add(id,menuArray.getString(m));
}//menu for loop
//another for loop for imageArray...
}//end of restaurants loop
but then you have to add the menuMap and imageMap to an array list, called menus, images...
why don't you create an object to hold all info about restaurant
class restaurant{
private String name="", id =""....
//setters and getters ...
String menuItems[] = null;
String imageItems[] = null;
//setters getters for the arrays.
}
}
EDIT:
this sol does not need a new maps, just add images and menu to same map
using dynamic key name
for(int m=0;m<menuArray.length();++m){
map.add("MENU_" + m,menuArray.getString(m));
}//menu for loop
map.add("TOTAL_MENU", Integer.toString(menuArray.length()));
you can use above code, to add menu items to the map
and same thing to images, "IMAGE_"+m
and TOTAL_IMAGES
now at target activity, read all IMAGE_n and MENU_n in a loop
from 0 to TOTAL_IMAGES, and TOTAL_MENU

Related

Why is my public variable being shown as " 'this' is not available"?

I am trying to populate a listview with data from a database but it won't allow me to assign a string variable.
i have read some other articles on this but i cannot for the life of me figure out why my variable is shown as " 'this' is not available " When i use the debugger.
public class InventoryActivity extends AppCompatActivity
{
private RecyclerView varRecyclerView;
private RecyclerView.Adapter varAdapter;
private RecyclerView.LayoutManager varLayoutManager;
private static String URL_FindInventory = "MyPHPFile";
//IM TRYING TO SET THESE TWO VARIABLES
public String itemOneName, itemOneEffect;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
String characterID = getIntent().getStringExtra("characterID");
ArrayList<LayoutItem> inventoryList = new ArrayList<>();
FindInventory(characterID);
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, "Item Two Name", "Item Two's Effect"));
varRecyclerView = findViewById(R.id.recyclerView);
varRecyclerView.setHasFixedSize(true);
varLayoutManager = new LinearLayoutManager(this);
varAdapter = new LayoutAdapter(inventoryList);
varRecyclerView.setLayoutManager(varLayoutManager);
varRecyclerView.setAdapter(varAdapter);
}
private void FindInventory(final String characterID)
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_FindInventory,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONObject jsonObject = new JSONObject(response);
String result = jsonObject.getString("result");
if (result != null)
{
JSONArray jsonArray = jsonObject.getJSONArray("result");
for(int i = 0; i < jsonArray.length(); i++)
{
JSONObject object = jsonArray.getJSONObject(i);
//IM TRYING TO USE THESE TWO VARIABLES TO SET THE PUBLIC ONES.
String itemName = object.getString("Name").trim(); // this has a value of "Cap of Thinking"
String itemEffect = object.getString("Effect").trim(); // this has a value of "Helps the user to think +2 Intelligence"
itemOneName = itemName; // THIS IS SHOWN AS "ItemOneName = 'this' is not available "
itemOneEffect = itemEffect; // THIS IS SHOWN AS "ItemOneEffect = 'this' is not available "
}
}
else if ((result.equals("error")))
{
Toast.makeText(InventoryActivity.this, "Cannot find Inventory", Toast.LENGTH_LONG).show();
}
} catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(InventoryActivity.this, "Exception Error " + e.toString(), Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(InventoryActivity.this, "Error " + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("characterid", characterID);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
When I'm trying to set the value of the 2 public strings they are being set as null, I can't for the life of me figure out why it won't allow me to set there value to the variables I read from the JSON object.
They are null because your web request happens after you added the items to the lists.
Make inventoryList a field and remove the two string fields you're trying to set
Move the two inventoryList.add methods into the onResponse, then you need to notify the RecyclerView adapter that new data needs to be displayed
The reason they are null is because when the compiler executes below two lines(let's call it line 1 and line 2):
FindInventory(characterID);//line 1
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));//line 2
-At line 1, the method gets executed asynchronously(means that it will not block the execution of line 2, line 2 will be executed either after or before line 1). This causes the variables itemOneName and itemOneEffect to be null, since line 2 was executed before line 1, remember line 1 and line 2 are being executed in parallel or same time.
To fix this:
-You have to do below:
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, "Item Two Name", "Item Two's Effect"));
...and other dependencies
After you invoke these lines within onResponse():
String itemName = object.getString("Name").trim(); // this has a value of "Cap of Thinking"
String itemEffect = object.getString("Effect").trim();

Update ListView Adapter input with radioButtons

My app fetches data from a server and shows it in a listView. I’m sorting the data and want to show them as well so I thought to use radioButtons to change the view. With every button another content should be loaded into the List which the adapter shows. The problem is that no view comes up, my screen stays blank unfortunately. How do I load them correctly and change the input onClick? (In this case I want to show contactList and contactListTwo with the radioButtons)
That‘s my code so far. The part that I spoke about is at the bottom:
public class CallsFragment extends Fragment{
private String TAG = MainActivity.class.getSimpleName();
private ListView lv;
private static String url = "xx";
int a = 1;
String title;
private BaseAdapter mContactsAdapter;
private RadioGroup rg;
RadioButton rb1;
RadioButton rb2;
RadioButton rb3;
private final List<HashMap<String, String>> mContactsListItems = new ArrayList<>();
ArrayList<HashMap<String, String>> contactList;
ArrayList<HashMap<String, String>> contactListTwo;
private static final int rb1id = 2;
private static final int rb2id = 1;
private static final int rb3id = 0;
public CallsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_calls, container, false);
contactList = new ArrayList<>();
contactListTwo = new ArrayList<>();
rg = (RadioGroup) view.findViewById(R.id.RGroup);
rb1 = (RadioButton) view.findViewById(R.id.radioButton5);
rb2 = (RadioButton) view.findViewById(R.id.radioButton4);
rb3 = (RadioButton) view.findViewById(R.id.radioButton6);
rb1.setId(rb1id);
rb2.setId(rb2id);
rb3.setId(rb3id);
((ListView) view.findViewById(R.id.list))
.setAdapter(mContactsAdapter);
return view;
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute () {
super.onPreExecute();
}
#Override
protected Void doInBackground (Void...arg0){
HttpHandler sh = new HttpHandler();
//request to url and getting response
String jsonStr = sh.makeServiceCall("https://creativecommons.tankerkoenig.de/json/list.php?lat=" + lat + "&lng=" + lon + "&rad=" + umkreis + "&sort=price&type="+ type +"&apikey=21f2ed18-88b1-5d26-34f3-28318713eaf4");
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("stations");
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString("id");
String price = c.getString("price");
//tmp hash map for single contact
HashMap<String, String> contact = new HashMap<>();
// adding each child node to HashMap key => value
contact.put("id",id);
contact.put("price", price);
//adding contact to contact list
contactList.add(contact);
}
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
return null;
}
#Override
protected void onPostExecute (Void result){
super.onPostExecute(result);
/**
* Updating parsed JSON data into ListView
* */
mContactsAdapter = new SimpleAdapter(
getActivity(), mContactListItems,
R.layout.list_item, new String[]{"price", "brand",
"dist", "street", "houseNumber", "postcode", "place"}, new int[]{R.id.stoff,
R.id.brand, R.id.dist, R.id.street, R.id.houseNumber, R.id.postCode, R.id.place});
mContactListItems.addAll(contactListTwo);
mContactsAdapter.notifyDataSetChanged();
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
mContactsListItems.clear();
switch (checkedId) {
case R.id.radioButton4:
mContactsListItems.addAll(contactList);
break;
case R.id.radioButton5:
mContactsListItems.addAll(contactListTwo);
break;
}
//mark as changed, update list
mContactsAdapter.notifyDataSetChanged();
}
});
}
}
You are passing one list object to your adapter (contactListTwo), but updating a different list object in your checked change listener (mContactsListItems). This means that your changes are totally invisible to your adapter.
To fix, change the list reference you pass to the adapter's constructor:
new SimpleAdapter(..., mContactsListItems, ...);
I notice that you never set the initial items to this list, so you may also have to call e.g. mContactsListItems.addAll(contactListTwo) before you create the adapter for the first time. That just depends on whether or not you want the list to be empty before the user changes the radio buttons.
Edit
There's a second problem: the way you assign your adapter to the ListView. In your onCreate(), I see this line:
((ListView) view.findViewById(R.id.list))
.setAdapter(mContactsAdapter);
At the point where this code runs, I don't see any initialization of mContactsAdapter, so unless you've omitted that code, this is going to be the same as writing setAdapter(null).
Later on, in onPostExecute(), you create a new adapter and assign it to mContactsAdapter. However, this doesn't actually affect the list view! You need to re-set the adapter if you re-assign its variable.
So you either have to initialize the adapter before you set it on your list view in onCreate() (which is fine to do even though you haven't loaded the data yet; the adapter will just be empty), or you have to call setAdapter() again in your onPostExecute() method to assign this new adapter to your list view.

Filter list view from ListAdapter in Android

Below is the code which will display the list of name in the list view.
I want to filter the list view based on the input of search textbox.
I have added the addTextChangedListener method for the edittext. But I am facing an error in getFilter() method as "can't resolve". As per the google I found the getFilter() method work on ArrayAdapter. I want to know how can I make getFilter() method work with ListAdapter.
Please can anyone let me know.
package com.smoothbalance.smothbalance;
public class AddedClientList extends CommonDrawer {
EditText searchTextBox;
ListAdapter adapter;
ListView addedlistofclient;
// JSON Nodes
private static final String TAG_CONTACTS = "data";
private static final String TAG_ID = "id";
private static final String TAG_FULL_NAME = "full_name";
private static final String TAG_EMAIL = "email";
//JSON array
JSONArray json_data = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> dataList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.activity_added_client_list, null, false);
mDrawerLayout.addView(view, 0);
addedlistofclient = (ListView) findViewById(R.id.listView_Added_Client);
searchTextBox = (EditText) findViewById(R.id.Search_added_clients);
dataList = new ArrayList<HashMap<String, String>>();
if (CommonFunctions.isNetworkAvailable(getBaseContext())) {
params.add(new BasicNameValuePair("", user_id));
new Added_client_list().execute();
} else {
Toast.makeText(getApplicationContext(), "Network Not Available... \n Please check Your Wifi Connection or Mobile Network", Toast.LENGTH_LONG).show();
}
searchTextBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
AddedClientList.this.adapter.getFilter().filter(s);
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
private class Added_client_list extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... param) {
String network_error = null;
String url = getString(R.string.getClientlist) + user_id + "/Clients";
ServiceHandler serviceHandler = new ServiceHandler();
String jsonStr = serviceHandler.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
network_error = jsonStr;
if (jsonStr != null) {
try {
JSONObject jsonObject = new JSONObject(jsonStr);
// getting json array node
json_data = jsonObject.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < json_data.length(); i++) {
JSONObject c = json_data.getJSONObject(i);
String id = c.getString(TAG_ID);
String full_name = c.getString(TAG_FULL_NAME);
String email = c.getString(TAG_EMAIL);
// tmp hashmap for single data
HashMap<String, String> data = new HashMap<String, String>();
// adding each child node to HashMap key => value
data.put(TAG_ID, id);
data.put(TAG_FULL_NAME, full_name);
data.put(TAG_EMAIL, email);
// adding contact to contact list
dataList.add(data);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return network_error;
}
#Override
protected void onPostExecute(String aVoid) {
adapter = new SimpleAdapter(AddedClientList.this, dataList, R.layout.customelistview, new String[]
{TAG_FULL_NAME, TAG_EMAIL,}, new int[]{R.id.details, R.id.serviceData});
addedlistofclient.setAdapter(adapter);
}
}
As Luksprog mentioned in the comment, ListAdapter is not filterable, you would have either have to create a customAdapter by extending the listadapter and implementing filterable in that object, or use an adapter provided by the sdk that implementals filterable

Cannot resolve method 'getStringArrayList' when I'm making a search filter for Listview

I'm a beginner, I'm creating a job search app which shows job infomation as listview where the data is from WAMP server database. I encounter a problem : Cannot resolve method 'getStringArrayList' , when I'm making a search filter for this Listview. Please see line 11 of SearchFilter.java. Could anyone help? thank you very much!
SearchFilter.java
public class SearchFilter extends ListActivity {
private EditText filterText = null;
ArrayAdapter<String> adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList())); ***<<<<< this line !***
}
private TextWatcher filterTextWatcher = 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) {
adapter.getFilter().filter(s);
}
};
#Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}
}
MainActivity.java
public class MainActivity extends ListActivity {
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String url = "http://192.168.0.102/get_json_select_all.php";
// JSON Node names
private static final String TAG_INFO = "info";
private static final String TAG_POSTNAME = "PostName";
private static final String TAG_LOCATION = "Location";
private static final String TAG_SALARY = "Salary";
private static final String TAG_RESPONSIBILITY = "Responsibility";
private static final String TAG_COMPANY = "Company";
private static final String TAG_CONTACT = "Contact";
// contacts JSONArray
JSONArray infos = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> infoList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoList = new ArrayList<HashMap<String, String>>();
final ListView lv = getListView();
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.PostName))
.getText().toString();
String cost = ((TextView) view.findViewById(R.id.Location))
.getText().toString();
String description = ((TextView) view.findViewById(R.id.Salary))
.getText().toString();
HashMap<String, String> info = new HashMap<String, String>();
info=(HashMap<String, String>)lv.getAdapter().getItem(position);
// Starting single contact activity
Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_POSTNAME, name);
in.putExtra(TAG_LOCATION, cost);
in.putExtra(TAG_SALARY, description);
in.putExtra(TAG_RESPONSIBILITY, info.get(TAG_RESPONSIBILITY));
in.putExtra(TAG_COMPANY, info.get(TAG_COMPANY));
in.putExtra(TAG_CONTACT, info.get(TAG_CONTACT));
startActivity(in);
}
});
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
infos = jsonObj.getJSONArray(TAG_INFO);
// looping through All Contacts
for (int i = 0; i < infos.length(); i++) {
JSONObject c = infos.getJSONObject(i);
String id = c.getString(TAG_POSTNAME);
String name = c.getString(TAG_LOCATION);
String email = c.getString(TAG_SALARY);
String address = c.getString(TAG_RESPONSIBILITY);
String gender = c.getString(TAG_COMPANY);
// Phone node is JSON Object
String mobile = c.getString(TAG_CONTACT);
// tmp hashmap for single contact
HashMap<String, String> info = new HashMap<String, String>();
// adding each child node to HashMap key => value
info.put(TAG_POSTNAME, id);
info.put(TAG_LOCATION, name);
info.put(TAG_SALARY, email);
info.put(TAG_RESPONSIBILITY, address);
info.put(TAG_COMPANY, gender);
info.put(TAG_CONTACT, mobile);
// adding contact to contact list
infoList.add(info);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, infoList,
R.layout.list_item, new String[] { TAG_POSTNAME, TAG_LOCATION,
TAG_SALARY }, new int[] { R.id.PostName,
R.id.Location, R.id.Salary });
setListAdapter(adapter);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return (super.onCreateOptionsMenu(menu));
}
}
activity_main.xml
<EditText android:id="#+id/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Search Jobs"
android:inputType="text"
android:maxLines="1"/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
getStringArrayList is a method on Bundle (such as savedInstanceState). There's no such method in Activity. Hope that helps.
Currently your infoList is an ArrayList>, something that is harder to pass directly to an activity. So find a way to represent it as an ArrayList, or find a more suitable datatype supported by Intent's putExtra-methods. Here below is a suggested solution using an ArrayList.
Passing the data into the activity with the Intent allows you to get it back in your SearchFilter. In the calling activity put something like this:
Intent i = new Intent(this, SearchFilter.class);
i.putStringArrayListExtra("com.yourpackagename.here.keynamehere", aStringArrayList);
In SearchFilter.java, put something like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);
Intent startingIntent = getIntent();
ArrayList<String> arrayList = new ArrayList<String>();
if (startingIntent != null) {
arrayList = startingIntent.getStringArrayList("com.yourpackagename.here.keynamehere");
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
arrayList));
}

how to request an url with an edittext

i need to find a way to request an url with an edit text and display the json of that url. i have tried to use this code :
// URL to get contacts JSON
private static String id = null;
private static String url = "http://api.ccapp.it/v1/student/" + id + "/schedule/11";
// JSON Node names
private static final String TAG_LESSON = "class";
private static final String TAG_ROOM = "room";
private static final String TAG_TEACHER = "teacher";
// contacts JSONArray
JSONArray contacts = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.roosteralluz);
//number input
final EditText input = (EditText) findViewById(R.id.editText2);
//search button
Button btnSearch = (Button) findViewById(R.id.button34);
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
id = input.getText().toString();
// Calling async task to get json
new GetContacts().execute();
}
});
But when i try that code it returns this error: org.json.JSONException: Value <html><head><title>Slim of type java.lang.String cannot be converted to JSONObject
It is able to parse a link if i change id (look at code) to my own id. but i need to find a user his own id with an edittext.
Instead of using JsonArray, try Gson library to convert from Json to String and vice versa.

Categories