How to implement notifysetDatachanged method in android? - android

I am developing an app in which i have a listview which contain some data from server and for this i am using json and also implemented adapter.notifyDataSetchanged() but i want to know whether i am doing in a write way or not pls check.
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
m_VcomData = new CVcomStorage();// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
m_VcomAdpter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);

First of all you need to write m_VcomAdpter.notifyDataSetChanged(); outside of the for loop because it will call again and again util your loops count.
2nd thing if you are creating or initalizing adapter after your api call then you don't need to call notifyDataSetChanged method.
So directly call this after for loop
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
3rd thing if you modified your array then you can call like
m_VcomAdpter.notifyDataSetChanged()
e.g.
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
m_VcomData = new CVcomStorage();// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
}
} catch (Exception e) {
e.printStackTrace();
}
}
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);

notifyDatasetChanged() used for update the ListView item.
Suppose you have deleted or added something in your list in your case "s_VcomDataSet".
you should use notifyDatasetChanged() that reflects new changes in data and notifies ti listview.
For better usability you should use RecyclerView in place of listview

You should set the adapter before calling notifyDatasetChanged() on it. Your code should be along following lines-
CVcomStorage m_VcomData = new CVcomStorage();
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
m_VcomAdpter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}

Related

why Setter Getter class variable only gets the last object from JSON, android,recyclerView

I just want to know why my Setter Getter class variable only gets the last object from JSON? it is supposed to fetch all json objects to setter getter variable so that it could transfer it to recyclerview.
Here is part of the Code, Im a begginer, pls help
JSONArray json = req
.getJSONArray("worldpopulation");
for (int i = 0; i < json.length(); i++) {
JSONObject jsonOb = json
.getJSONObject(i);
setterGetterClass = new SuperHeroes(jsonOb.getInt(Configg.TAG_rank),jsonOb.getString(Configg.TAG_country),jsonOb.getString(Configg.TAG_population),jsonOb.getString(Configg.TAG_flag));
Log.d("tag", setterGetterClass.getcountry().toString());
Log.d("show: ", setterGetterClass.toString());
}
Log.d("parseData: ", setterGetterClass.toString());
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
You for loop iterates & every time it initializes a new SuperHeroes instance to setterGetterClass. So after last iteration it will hold the last JsobObject data. Try
Create an ArrayList.
ArrayList<SuperHeroes> superHeroesList = new ArrayList<SuperHeroes>();
Inside your for loop
SuperHeroes superHeroes = new SuperHeroes(jsonOb.getInt(Configg.TAG_rank),jsonOb.getString(Configg.TAG_country),jsonOb.getString(Configg.TAG_population),jsonOb.getString(Configg.TAG_flag);
superHeroesList.add(superHeroes);
Now superHeroesList will have all your json objects.
You are setting the "setterGetterClass" variable in every iteration of your for loop. When your loop ends, your "setterGetterClass" will have the last value of your JSONArray. That is the reason you get every time the last value. If you want to fetch all values, then you should add them to a list or similar structure. For example:
JSONArray json = req.getJSONArray("worldpopulation");
List<SuperHeroe> superHeroeList = new ArrayList<>();
for (int i = 0; i < json.length(); i++) {
SuperHeroe superHeroe = new SuperHeroe(jsonOb.getInt(Configg.TAG_rank),jsonOb.getString(Configg.TAG_country),jsonOb.getString(Configg.TAG_population),jsonOb.getString(Configg.TAG_flag));
superHeroeList.add(superHeroe);
}
Then you'll have all the objects contained in the "superHeroeList" ArrayList.

Why do I get an empty response when my android app calls my API on my server?

I have android application that called information and show it as a list.
I have a spinner when you choose the date from the spinner you get the information related to that date.
In the app first load it calls automatically today information.
this is the code I use in my main activity to create my spinner and fill it with elements and handle the clicks on each item:
// Spinner element
spinner = (Spinner) v.findViewById(R.id.spinner);
// Spinner click listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
// On selecting a spinner item
//String item = parent.getItemAtPosition(position).toString();
switch(position){
case 3:
if (JsonUtils.isNetworkAvailable(getActivity())) {
list.clear();
new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=-1");
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
}
break;
case 4:
if (JsonUtils.isNetworkAvailable(getActivity())) {
list.clear();
new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0");
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
}
break;
case 5:
if (JsonUtils.isNetworkAvailable(getActivity())) {
list.clear();
new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=1");
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
}
break;
default:
if (JsonUtils.isNetworkAvailable(getActivity())) {
list.clear();
new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0");
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
calendar.add(Calendar.DAY_OF_YEAR, -1);
Date yesterday = calendar.getTime();
calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, 1);
Date tomorrow = calendar.getTime();
DateFormat dateFormat = new SimpleDateFormat("dd/MM EEE");
String todayAsString = dateFormat.format(today);
String tomorrowAsString = dateFormat.format(tomorrow);
String yesterdayAsString = dateFormat.format(yesterday);
// Spinner Drop down elements
List<String> categories = new ArrayList<String>();
categories.add(yesterdayAsString);
categories.add(todayAsString);
categories.add(tomorrowAsString);
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_item, categories);
dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
spinner.setSelection(4);
The problem : first load of the app is calling the data of today (which is the default choice in my spinner) without any problem.
if i choose another element in the spinner it also calls the related data without problem.
now if I want to select back today element in the spinner no data will be brought from the server even when the app at the start up it calls data from the same link and get it.
I get this message in my log :
W/System.err: org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject
The onPostExcute of my Asynktask contains this code:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != progressDialog && progressDialog.isShowing()) {
progressDialog.dismiss();
}
if (null == result || result.length() == 0) {
Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show();
} else {
try {
Log.d("resultTT",result);
JSONObject mainJson = new JSONObject(result);
JSONArray jsonArray = mainJson.getJSONArray(JsonConfig.CATEGORY_ARRAY_NAME);
JSONObject objJson = null;
for (int i = 0; i < jsonArray.length(); i++) {
objJson = jsonArray.getJSONObject(i);
ItemMatch objItem = new ItemMatch();
objItem.setMatchId(objJson.getString(JsonConfig.Match_ID));
objItem.setMatchTournamentName(objJson.getString(JsonConfig.Match_LEAGUE_NAME));
objItem.setMatchTime(objJson.getString(JsonConfig.Match_TIME));
objItem.setMatchStatus(objJson.getString(JsonConfig.Match_STATUS));
objItem.setMatchLocalTeamName(objJson.getString(JsonConfig.Match_LOCALTEAM_NAME));
objItem.setMatchVisitorTeamName(objJson.getString(JsonConfig.Match_VISITORTEAM_NAME));
objItem.setMatchLocalTeamGoals(objJson.getString(JsonConfig.Match_LOCALTEAM_GOALS));
objItem.setMatchVisitorTeamGoals(objJson.getString(JsonConfig.Match_VISITORTEAM_GOALS));
objItem.setMatchBestOddPercent(objJson.getString(JsonConfig.Match_BEST_ODD_PERCENT));
objItem.setMatchBestOddResult(objJson.getString(JsonConfig.Match_BEST_ODD_RESULT));
list.add(objItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
for (int j = 0; j < list.size(); j++) {
object = list.get(j);
array_match_id.add(String.valueOf(object.getMatchId()));
str_match_id = array_match_id.toArray(str_match_id);
array_league_name.add(String.valueOf(object.getMatchTournamentName()));
str_league_name = array_league_name.toArray(str_league_name);
array_match_time.add(String.valueOf(object.getMatchTime()));
str_match_time = array_match_time.toArray(str_match_time);
array_match_status.add(String.valueOf(object.getMatchStatus()));
str_match_status = array_match_status.toArray(str_match_status);
array_match_localteam_name.add(object.getMatchLocalTeamName());
str_match_localteam_name = array_match_localteam_name.toArray(str_match_localteam_name);
array_match_visitorteam_name.add(object.getMatchVisitorTeamName());
str_match_visitorteam_name = array_match_visitorteam_name.toArray(str_match_visitorteam_name);
array_match_localteam_goals.add(object.getMatchLocalTeamGoals());
str_match_localteam_goals = array_match_localteam_goals.toArray(str_match_localteam_goals);
array_match_visitorteam_goals.add(object.getMatchVisitorTeamGoals());
str_match_visitorteam_goals = array_match_visitorteam_goals.toArray(str_match_visitorteam_goals);
array_match_best_odd_percent.add(object.getMatchBestOddPercent());
str_match_best_odd_percent = array_match_best_odd_percent.toArray(str_match_best_odd_percent);
array_match_best_odd_result.add(object.getMatchBestOddResult());
str_match_best_odd_result = array_match_best_odd_result.toArray(str_match_best_odd_result);
}
setAdapterToListView();
}
In the try section of this code u can see I make a log of the result to see what is coming from the server i just get this : D/resultTT: []
and as you see the try is inside the else section so in the if statement of this section i check if the result is null or empty ; but the code passes it and enter the else statement but still showing that the returned result array is empty.
I want some help to find the reason behind this empty returned array even it loads fine at the start up. why can not it get the information after I choose any element in the spinner and then come back to the default (today) element?
UPDATE : this is my php side-server api code
<?php
include_once ('includes/variables.php');
DEFINE ('DB_HOST', $host);
DEFINE ('DB_USER', $user);
DEFINE ('DB_PASSWORD', $pass);
DEFINE ('DB_NAME', $database);
$mysqli = #mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) OR die ('Could not connect to MySQL');
#mysql_select_db (DB_NAME) OR die ('Could not select the database');
?>
<?php
mysql_query("SET NAMES 'utf8'");
$date_offset = mysql_real_escape_string($_GET[d_o]);
//$date_offset = 0;
if(empty($date_offset) || $date_offset == "0")
{
$date_offset_value = "0";
$query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20";
$resouter = mysql_query($query);
}
else
{
$date_offset_value = $date_offset;
$query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20";
$resouter = mysql_query($query);
}
$set = array();
$total_records = mysql_num_rows($resouter);
if($total_records >= 1){
while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)){
$set['NewsApp'][] = $link;
}
}
echo $val= str_replace('\\/', '/', json_encode($set));
?>
If you get an array in return when expecting an object, there might be something wrong with the request to the API. One way is to figure it out it set up Wireshark on the development machine to sniff and filter the traffic. Then you can see if your request is faulty.
It is possible that the value of the response argument from the onPostExecute method contains stringified JSONArray, not JSONObject.
You can always test this with:
try:
JSONArray jsonArray = new JSONArray(result);
catch(JSONException e) {
// String `result` is not an array. Parse it as a regular JSONObject.
}
Testing wheter string is an empty json array (depends on it's formatting, especially when it may contain some white characters) checking it's length might be a pretty bad idea.
It all depends how are determined an API endpoints that you are calling.
One more tip at the end. If you are planning to consume REST API I strongly recommend using:
Retrofit - which allows you to easily define interfaces to access your API,
GSON - to automatically convert responses for Java models.
Your result string is an empty array but not an empty string. The empty array is represented as the following string:
String result = "[]";
In that case result.length() is equal to 2.
When parsing JSON you need to know if the parsed object is of type Object or of type Array. The former one is wrapped with braces {}, the later one with square brackets [].
So the following line:
JSONObject mainJson = new JSONObject(result);
Should probably be:
JSONArray mainJson = new JSONArray(result);
But I cannot emphasize enough that you need to know what your API returns if you want to be able to parse it correctly.
EDIT:
Well, json_encode will have a hard time to guess whether it should create a JSON Array or a JSON Object out of the empty array that you created with $set = array();.
Adding objects to the array like you do in your loop makes it obvious for json_encode that it should create a JSON Object.
I don't know if you can force json_encode's behavior, but worst case you could check yourself if the array is empty and return "" or null if the array is empty.
$set = array();
$total_records = mysql_num_rows($resouter);
if ($total_records >= 1) {
while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)) {
$set['NewsApp'][] = $link;
}
echo $val= str_replace('\\/', '/', json_encode($set));
} else {
echo $val="";
}
please put a check result.isEmpty() in your try block condition may this could solve your problem.
you can not directly get response in string . it can use JSONObject and JSONArray.

Android for-loop getting stuck in endless loop

I have a JSONArray of JSONObjects in each of which is a string with the key "kind". I'm trying to loop through the JSONarray and organize them by "kind" to use to fill a SeperatedListAdapter. what I am trying to achieve is this structure
{
communications[
{ "header":"kind"
communications[
{}
{}
{}
{}
]
}
{ "header":"kind"
communications[
{}
{}
{}
{}
]
}
]
}
The problem I'm having is the for loop i have created to achieve this gets stuck in an endless loop and thus crashes the application. Does anyone know where I am going wrong with this?
Here's my code I know it gets stuck in a loop as it runs the log "1" about 1000 times even though I know there's only 5 things in the array I'm passing in.
for(int i = 0; i < communicationsFromFile.length(); i++){
JSONObject communication = communicationsFromFile.getJSONObject(i);
Log.v("Communications", "kind = " + communication.getString("kind"));
Log.v("Communications", "newComArray = " + newComArray);
if(newComArray.length() != 0){
Log.v("Communications", "newComArray IsNotempty");
for(int a = 0; a < newComArray.length();a++){
JSONObject itemInArray = newComArray.getJSONObject(a);
JSONArray communicationsForKind = itemInArray.getJSONArray("communications");
Log.v("Communications", "1");
if(itemInArray.getString("header").equals(communication.getString("kind"))){
Log.v("Communications", "Header Exists");
communicationsForKind.put(communication);
itemInArray.put("communications", communicationsForKind);
newComArray.put(itemInArray);
}else{
Log.v("Communications", "Header Does not Exist");
JSONObject addItemInArray = new JSONObject();
JSONArray addArrayToItem = new JSONArray();
addArrayToItem.put(communication);
addItemInArray.put("header", communication.getString("kind"));
addItemInArray.put("communications", addArrayToItem);
newComArray.put(addItemInArray);
}
}
}else{
JSONObject addItemInArray = new JSONObject();
JSONArray addArrayToItem = new JSONArray();
addArrayToItem.put(communication);
addItemInArray.put("header", communication.getString("kind"));
addItemInArray.put("communications", addArrayToItem);
newComArray.put(addItemInArray);
}
}
In each iteration of the inner for loop, you put new objects in the newComArray. The condition a < newComArray.length() is always satisfied because a and the array length both grow at the same rate.

JSON parsing returning a null value

I am trying to parse the response i get from the network database. I am getting only one value i.e. seller id in response. When i try to pass it in JSON Object, somehow the toast after it doesn't execute and the toast after it is not executed.
I know there are many related questions but i can't find whats wrong... please help. Thanks.
try {
JSONArray jArray = new JSONArray(stuff.toString());
Toast.makeText(this, "len: " + jArray.length(), 1000).show(); // length is 1
for (int i = 0; i < jArray.length(); i++) {
Toast.makeText(this, "Arr: " + stuff, 1000).show();
// Arr: [{"seller_id":"5"}]
JSONObject jObject = jArray.getJSONObject(i);
j_id = jObject.getString(stuff);
// not getting executed
Toast.makeText(this, "JSON: " + j_id, 1000).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
Toast.makeText(this, "View: " + j_id, 1000).show(); // j_id is giving null value
This is my json data [{"seller_id":"5"}] i am trying to get the value of seller id (ie 5 here) out of it.
There is a problem in jObject.getString() method args
JSONObject jObject = jArray.getJSONObject(i);
j_id = jObject.getString(stuff);
Your giving the array. It should the name of the object i.e seller_id
so after the modification your code would be j_id = jObject.getString("seller_id");
After the following code:
j_id = jObject.getString(stuff);
add textview.settext(j_id);
and change this textview with your textview name
and if its not working than show your complete json data.

Adding an unknown amount of items to a List in a Dialog for my Android app

I'm trying to cycle through a JSONObject to see how many passengers there are, and then I want to display them all nicely in a dialog window. It looks like there are a few ways to do it, but overall I'm just confused on how to go about it. This is the closest I've gotten, it works but as you can see I'm only adding one item. So there is only one item displaying in my alertdialog, and there should be a couple more. My alertdialog (called ticketbuilder) is created somewhere else, I'm just trying to add everything in this for loop. How do I add all of my passengers to the list to display? Thanks a ton in advance!
for (int i = 0; i < tickets.length(); i++) {
final int ticketCount = i;
JSONObject ticket;
try {
ticket = tickets.getJSONObject(ticketCount);
passengername = ticket.getString("passengername");
ticketnumber = ticket.getString("ticketnumber");
CharSequence[] array = {passengername + " \n" + ticketnumber};
ticketBuilder.setItems(array, null); //adding to my dialog
} catch (JSONException e) {
System.out.println(e);
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try putting the CharSequence outside the loop and init it like this:
CharSequence[] array = new CharSequence[tickets.length()];
Then in the loop add thing to the array:
array[i] = {passengername + " \n" + ticketnumber};
Move ticketBuilder.setItems so it is after, outside the loop.

Categories

Resources