I am executing getMessages() every minute and it jumps everytime to the top because of the
myadapter.notifyDataSetChanged();
How can I make so that the Recyclerview holds it's position even if it's updated or not?
private void getMessages() {
StringRequest request = new StringRequest(Request.Method.POST, uRl, response -> {
try{
if (lstMessages != null) {
lstMessages.clear();
}
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
chatModel um = new chatModel();
um.setM_msg(jsonObject.getString("message"));
lstMessages.add(um);
} catch (JSONException e) {
e.printStackTrace();
}
}
}catch (JSONException e2){
e2.printStackTrace();
}
if (!started) {
layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
rv_msg.setLayoutManager(layoutManager);
chat myadapter = new chat(this, lstMessages);
rv_msg.setAdapter(myadapter);
start();
} else {
chat myadapter = new chat(this, lstMessages);
myadapter.notifyDataSetChanged();
}
}, error -> {
MySingleton.getmInstance(this).MySingletonClear(this);
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> param = new HashMap<>();
param.put("aa", String.valueOf(aa));
param.put("bb", String.valueOf(bb));
return param;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(30000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getmInstance(this).addToRequestQueue(request);
}
If you clear list of data and use notifyDataSetChanges() recyclerview will refresh all items.
You can use distinct function to prevent duplicate data.
Here is an example distinct function:
private void distinctMessages(List<Message> newMessages) {
if (lstMessages.size() < 1 || lstMessages == null) {
lstMessages.addAll(newMessages);
return;
}
for (Message newMessage: newMessages) {
boolean hasSameMessages = false;
for (Message currentMessage: lstMessages) {
if (newMessage.getId().equals(currentMessage.getId())) {
hasSameMessages = true;
break;
}
}
if (!hasSameMessages) {
lstMessages.add(newMessage);
}
}
}
And you can use it in your existing code like this :
private void getMessages() {
StringRequest request = new StringRequest(Request.Method.POST, uRl, response -> {
try{
ArrayList<Message> newMessages = new ArrayList<Message>;
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
chatModel um = new chatModel();
um.setM_msg(jsonObject.getString("message"));
newMessages.add(um);
} catch (JSONException e) {
e.printStackTrace();
}
}
distinctMessages(newMessages);
}catch (JSONException e2){
e2.printStackTrace();
}
if (!started) {
layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
rv_msg.setLayoutManager(layoutManager);
chat myadapter = new chat(this, lstMessages);
rv_msg.setAdapter(myadapter);
start();
} else {
chat myadapter = new chat(this, lstMessages);
myadapter.notifyDataSetChanged();
}
}, error -> {
MySingleton.getmInstance(this).MySingletonClear(this);
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> param = new HashMap<>();
param.put("aa", String.valueOf(aa));
param.put("bb", String.valueOf(bb));
return param;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(30000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getmInstance(this).addToRequestQueue(request);
}
Please take a look Android Documentation
Try Adding this code
View v = rv_msg.getChildAt(0);
int top = (v == null) ?0 : v.getTop();
layoutManager.scrollToPositionWithOffset(lstMessages.size(), top);
after myadapter.notifyDataSetChanged();
Have you tried notifyItemRangeChanged(int positionStart, int itemCount) ? You have to use this instead of notifyDataSetChanged() while appending new items.
Add a method inside your adapter like below:
public void appendListToAdapter(List<String> list) {
int currentListSize = this.mList.size();
this.mList.addAll(list);
notifyItemRangeChanged(currentListSize, list.size());
}
Just grab the old list size into currentListSize and pass it to method.
Now call this method when you need to append your list with new messages.
Related
server data
android data
I am passing arraylist of srid of all element and post to server using volley request.enter image description here
here is the code
public class AttendenceShowStdList extends AppCompatActivity {
ActivityAttendenceShowStdListBinding AttendenceShowStdList;
ArrayList<AttStdListModel> userlist = new ArrayList<>();
ArrayList<AllStdListsrIdAdmIdModel> list= new ArrayList<>();
ArrayList<AllStdListModel> stdlist = new ArrayList<>();
AttStdListAdapter adapter;
private DatePickerDialog datePickerDialog;
private String date,clid,sectionId,yrId,instId,usid,usType,attdate;
SharedPreferences sharedPreferences_teach;//staff shareprefferece for profile fetch
private static final String SHARED_PREF_NAME_TEACH="myprefteach";
private static final String Key_USID_TEACH = "techusid";
private static final String Key_INSTID_TEACH = "techinstid";
private static final String Key_USTYPE_TEACH = "techustype";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AttendenceShowStdList= ActivityAttendenceShowStdListBinding.inflate(getLayoutInflater());
setContentView(AttendenceShowStdList.getRoot());
sharedPreferences_teach =getSharedPreferences(SHARED_PREF_NAME_TEACH, Context.MODE_PRIVATE);
instId=sharedPreferences_teach.getString(Key_INSTID_TEACH,null);
usid=sharedPreferences_teach.getString(Key_USID_TEACH,null);
usType=sharedPreferences_teach.getString(Key_USTYPE_TEACH,null);
//getting data from TakeAttendenceAdapter cardview
clid=getIntent().getExtras().getString("ClassId");
sectionId=getIntent().getExtras().getString("sectionId");
Log.d("cliddd",clid);
yrId=getIntent().getExtras().getString("YearId");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
date = sdf.format(new Date());
Log.d("dttt",date);
userlist = (ArrayList<AttStdListModel>) getModel(false);
adapter = new AttStdListAdapter(this,userlist);
AttendenceShowStdList.rvstdlist.setAdapter(adapter);
AttendenceShowStdList.rvstdlist.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
// recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
// recyclerView.setHasFixedSize(true);
getData();
//toolbar
setSupportActionBar(AttendenceShowStdList.toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
AttendenceShowStdList.submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
submitAttendence();
// Intent intent = new Intent(AttendenceShowStdList.this,SubmitAttendenceActivity.class);
// startActivity(intent);
}
});
}
private List<AttStdListModel> getModel(boolean isSelect){
List<AttStdListModel> list = new ArrayList<>();
for(int i = 0; i < list.size(); i++){
AttStdListModel model = new AttStdListModel();
model.setSelected(isSelect);
// model.setStud_name(String.valueOf(list.get(i)));
model.setAdmi_id(String.valueOf(list.get(i)));
list.add(model);
}
return list;
}
private void getData() {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url1="https://comzent.in/wonderschoolerp/apis/teacher/get_studteachers_att.php";
StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onResponse(String response) {
// Toast.makeText(getContext(), "Data added to API", Toast.LENGTH_SHORT).show();
try {
JSONObject respObj = new JSONObject(response);
JSONArray jsonArray5=respObj.getJSONArray("studatt_details");
Log.d("std details",jsonArray5.toString());
for(int i=0;i<jsonArray5.length();i++){
JSONObject jsonObject=jsonArray5.getJSONObject(i);
String sr_id=jsonObject.optString("sr_id");
String admi_id=jsonObject.optString("admi_id");
String stud_name=jsonObject.optString("stud_name");
String stud_phone=jsonObject.optString("stud_phone");
String stud_email=jsonObject.optString("stud_email");
String attd_status=jsonObject.optString("attd_status");
String attd_reason=jsonObject.optString("attd_reason");
userlist.add(new AttStdListModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
attd_status,attd_reason));
Log.d("s", String.valueOf(userlist));
list.add(new AllStdListsrIdAdmIdModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
attd_status,attd_reason));
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter=new AttStdListAdapter(getApplicationContext(),userlist);
AttendenceShowStdList.rvstdlist.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("get_studattd","1");
params.put("us_id",usid);
params.put("inst_id",instId);
params.put("class_id",clid);
params.put("sec_id",sectionId);
params.put("ay_id",yrId);
params.put("stud_attend_date",date);
return params;
}
};
queue.add(request);
}
//submit attendence
private void submitAttendence() {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url1="https://comzent.in/wonderschoolerp/apis/teacher/take_studteacher_att.php";
StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Toast.makeText(getContext(), "Data added to API", Toast.LENGTH_SHORT).show();
try {
JSONObject respObj = new JSONObject(response);
String msg=respObj.getString("message");
Toast.makeText(AttendenceShowStdList.this, msg, Toast.LENGTH_LONG).show();
Log.d("response msg",msg);
if(msg.equals("Attendance Generated Successfully..!")){
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_LONG).show();
Log.d("error msg", String.valueOf(error));
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
ArrayList<String> allstdsrid = new ArrayList<String>();
for(int i=0; i < list.size(); i++) {
allstdsrid.add(String.valueOf(list.get(i).getSr_id()));
}
params.put("sr_id", String.valueOf(allstdsrid));
Log.d("params", String.valueOf(params));
Log.d("allstudentsrid", String.valueOf(allstdsrid));
ArrayList<String> allstdadmid = new ArrayList<String>();
for(int i=0; i < list.size(); i++) {
allstdadmid.add(list.get(i).getAdmi_id());
params.put("admission_id", String.valueOf(allstdadmid));
}
Log.d("allstudentsadmid", String.valueOf(allstdadmid));
///selected student list
ArrayList<String> attstd = new ArrayList<String>();
for (int i = 0; i < AttStdListAdapter.userlist.size(); i++) {
if (AttStdListAdapter.userlist.get(i).getSelected()) {
attstd.add(AttStdListAdapter.userlist.get(i).getAdmi_id());
}
}
params.put("student_attend_submit","1");
params.put("class_id",clid);
params.put("sec_id",sectionId);
params.put("ay_id",yrId);
params.put("att_status", String.valueOf(attstd));
Log.d("params", String.valueOf(params));
params.put("stud_attend_date",date);
params.put("inst_id",instId);
params.put("us_id",usid);
params.put("us_type",usType);
return params;
}
};
queue.add(request);
}
//toolbar back to home
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId()==android.R.id.home){
finish();
}
return super.onOptionsItemSelected(item);
}
}
After submitting attendance, values of array of srid and admid retrive at server correctly ,problem is that only first record's srid and admid sets to '0' value.There is no problem when same Api is fetch on postman.
I apply cache but it works only one time when I click on first item it shows data after that when I click on another it shows same data how t fix it any guidelines
Here is my code
String URL = "http://facekart.azanic.com/Data_show_all_.php";
final ProgressDialog progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Fetcing, please wait...");
progressDialog.show();
StringRequest request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(s);
JSONArray jsonArray = jsonObject.getJSONArray("result");//getting array
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
Itemssetget it = new Itemssetget();
it.setName(jsonObject1.getString("name"));
it.setPhonenumber_seller(jsonObject1.getString("phonenumber_seller"));
it.setPrice(jsonObject1.getString("price"));
it.setDiscountprice(jsonObject1.getString("discountprice"));
it.setUnits(jsonObject1.getString("units"));
it.setStock(jsonObject1.getString("stock"));
it.setId(jsonObject1.getString("key_auto"));
it.setImageurl("http://facekart.azanic.com/images/" + jsonObject1.getString("imageurl"));
if (it.getStock().toString().equals("In stock")) {
items_random.add(it);
}
}
if (!items_random.isEmpty() && getActivity() != null) {
myAdapter = new homebuyer_fruits_adapter(getActivity(), items_random, homebuyer.phone_number_shop);
myAdapter.notifyDataSetChanged();
Random_list.addHeaderView(random_v);
Random_list.setAdapter(myAdapter);
Random_list.setSmoothScrollbarEnabled(true);
loadingdataprogress.stopShimmerAnimation();
loadingdataprogress.setVisibility(View.INVISIBLE);
// Toast.makeText(getContext(),"ADDED",Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getContext(), "Some error occurred -> " + volleyError, Toast.LENGTH_LONG).show();
;
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null) {
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new String(jsonString), cacheEntry);
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected void deliverResponse(String s) {
super.deliverResponse(s);
}
#Override
public void deliverError(VolleyError error) {
super.deliverError(error);
}
//adding parameters to send
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("s_number", homebuyer.phone_number_shop);
parameters.put("trig", "all");
return parameters;
}
};
RequestQueue rQueue = Volley.newRequestQueue(getContext());
rQueue.add(request);
Thanks in advance if any one help me in this I want every item click it shows data but first time it get from service second time it use from cache r any other method you can also suggest me How I smooth my app
I don't want to loading again and again
can anyone please help me i can not figure out the problem in the code. i only want to load the json response once when application startup or when activity reload but it loading json response twice in recylerview everytime when application start and making two copies of every json object retrive from server in my case there total 50 news channel in recylerview instead of 25 news channel
public class General extends Fragment
{
private static final String
URL = "https://newsapi.org/v1/sources?language=en&category=general&apiKey=0e1b2f7bc6bd4e1fbe0b40bea257dc97";
private final int android_image_urls[] =
{
R.drawable.abcnews,
R.drawable.aljazeera,
R.drawable.associatedpress,
R.drawable.bbcnews,
R.drawable.cnn,
R.drawable.googlenews,
R.drawable.independent,
R.drawable.metro,
R.drawable.mirror,
R.drawable.newsweek,
R.drawable.newyorkmagazine,
R.drawable.reddit,
R.drawable.reuters,
R.drawable.theguardianau,
R.drawable.theguardianuk,
R.drawable.thehindu,
R.drawable.thehuffingtonpost,
R.drawable.thenewyorktimes,
R.drawable.thetelegraph,
R.drawable.thetimesofindia,
R.drawable.thewashingtonpost,
R.drawable.time,
R.drawable.usatoday
};
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private ArrayList<AndroidVersion> androidVersions;
TextView textView;
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_general, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getContext(),3);
recyclerView.setLayoutManager(layoutManager);
textView = (TextView) rootView.findViewById(R.id.empty_view);
androidVersions = new ArrayList<>();
loadRecyclerViewData();
return rootView;
}
public void loadRecyclerViewData() {
final ProgressDialog progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading Data....");
progressDialog.show();
JsonObjectRequest data = new JsonObjectRequest(Request.Method.GET, URL,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(String.valueOf(response));
JSONArray array = jsonObject.getJSONArray("sources");
for (int i = 0; i < array.length(); i++) {
JSONObject o = array.getJSONObject(i);
AndroidVersion item = new AndroidVersion(
o.getString("name"),
android_image_urls[i],
o.getString("category")
);
androidVersions.add(item);
}
if (androidVersions.isEmpty()) {
recyclerView.setVisibility(View.GONE);
textView.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.VISIBLE);
textView.setVisibility(View.GONE);
}
adapter = new DataAdapter(androidVersions, getContext());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getContext(),"No Internet Connection", Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60*1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 1000 ; //24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null)
{
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString), cacheEntry);
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected void deliverResponse(JSONObject response) {
super.deliverResponse(response);
}
#Override
public void deliverError(VolleyError error) {
super.deliverError(error);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(data);
}
}
Your code is correct , it must not show the duplicate data , try removing the caching of data
In you onResponse you are not cleaning the androidVersions list. So each time your request is executed you add new items to your list. Most probably your request is executed twice (loadRecyclerViewData() is called twice?).
Try to clean or recreate androidVersions every time you fill it in onResponse.
I am calling api to fetch data from server and populating the data into Listview using adapter but data gets double itself everytime api getting called. ie:- on first time api call, list shows data like.
A
B
C
on second time api call, list gets data like..
A
B
C
A
B
C
here is my Fragment:
String GetChatURL = RECEIVING_URL+"receiptID="+userId+"&senderID="+recepientID;
StringRequest stringRequest = new StringRequest(Request.Method.GET, GetChatURL,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("respose valuee",response);
try {
JSONArray jsonArray = new JSONArray(response);
JSONObject jsonObject = new JSONObject();
JSONObject jsonObject1 = new JSONObject();
for(int i = 0;i<=jsonArray.length();i++) {
final ChatReceivingBean chatReceivingBean = new ChatReceivingBean();
jsonObject = jsonArray.getJSONObject(i);
chatReceivingBean.setMessageText(jsonObject.getString("MessageText"));
chatReceivingBean.setSenderID (jsonObject.getString ("senderID"));
chatArrayList.add (chatReceivingBean);
String id = chatReceivingBean.getSenderID ();
adapter = new ChatAdapter (getActivity(),chatArrayList,id);
messagesContainer.setAdapter(adapter);
scroll();
}
Log.e("stringgggg ",chatArrayList.toString ());
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(),error.toString(),Toast.LENGTH_LONG ).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<String,String>();
map.put(KEY_CHAT_RECEIVE_USERID,userId);
map.put(KEY_CHAT_RECEIVE_SENDERID,recepientID);
return map;
}
};
try {
RequestQueue requestQueue = Volley.newRequestQueue (getActivity ());
requestQueue.add (stringRequest);
}catch (Exception e){
}
Here is Adapter class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
sharedPreferences = context.getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
recepientID = sharedPreferences.getString("key_id",null);
userId = sharedPreferences.getString("key_name",null);
Log.d ("recepientID",recepientID);
Log.d ("userId",userId);
String iid = chatReceivingBeen.get (position).getSenderID ();
View v=convertView;
if(v==null)
{
if(chatReceivingBeen.get (position).getSenderID().equalsIgnoreCase(recepientID)){
//v = View.inflate(cxt, R.layout.right, null);
v= View.inflate (context, R.layout.list_item_chat_other,null);
}else {
// v = View.inflate(cxt, R.layout.left, null);
v= View.inflate (context, R.layout.list_item_chat,null);
}
}
txtMessage = (TextView)v.findViewById(R .id.txtMessage);
if(chatReceivingBeen!=null) {
// holder.txtMessage.setText (chatReceivingBeen.get (position).getMessageText ());
txtMessage.setText (chatReceivingBeen.get (position).getMessageText ());
}
return v;
}
clear chatArrayList before adding to it:
StringRequest stringRequest = new StringRequest(Request.Method.GET, GetChatURL,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("respose valuee",response);
try {
//clear
chatArrayList.clear()
JSONArray jsonArray = new JSONArray(response);
JSONObject jsonObject = new JSONObject();
JSONObject jsonObject1 = new JSONObject();
....
I'm posting "id" value (which i pass to this activity via getintent)
Uid = getIntent().getStringExtra("id");
to server and retrieving the corresponding jsonobjects.
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
When my jsonarray is empty, my app crashes. I want to toast"Error" when jsonarray is empty. How can I fix this?
Here is my code:
public class kill extends FragmentActivity {
GridView grid1;
CustomGrid_Album adapter;
private ProgressDialog pDialog;
String Uid,Disp;
public String category;
public String selected;
public static String imagename;
Button Alb_sel;
ArrayList<Item_album> gridArray = new ArrayList<Item_album>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.album_display);
grid1 = (GridView) findViewById(R.id.gridView2);
Uid = getIntent().getStringExtra("id");
Disp = getIntent().getStringExtra("disp");
Alb_sel=(Button)findViewById(R.id.album_to_select);
pDialog = new ProgressDialog(kill.this);
pDialog.setMessage("Loading...");
pDialog.show();
//fetching JSONArray
final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.POST, AppConfig.URL_Gallery4,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
} catch (JSONException e1) {
e1.printStackTrace();
}
int i=0;
for (i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
category = obj.getString("category_name");
selected = obj.getString("album_id");
imagename = obj.getString("org_image_name");
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
pDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "No images in this gallery", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
};
queue.add(stringRequest);
}
}
apply the check in onResponse
if(response.length()==0){
// error message
}else{
// your rest of the code
}
This looks problematic.
Datas.imageIds = new String[response.length()];
You don't want an array with the size of the string. You want an array of the size of the JSONArray within the response.
public void onResponse(String response) {
JSONArray arr = null;
try {
arr = new JSONArray(response);
Datas.imageIds = new String[arr.length()];
} catch (JSONException e1) {
e1.printStackTrace();
}
However, your code is going to continue on if an exception is thrown there, then you'll end up with a NullPointerException, so you should move the for-loop into the try-catch as well.
Realistically, though, you should just use a JSONArrayRequest if you're going to be expecting a JSONArray.
i want to toast"Error" when jsonarray is empty
Simple enough.
arr = new JSONArray(response);
if (arr.length() == 0) {
// TODO: Toast
}
I would simply add two checks to your onResponse method:
...
public void onResponse(String response) {
// Check if the response itself is an empty string or null
if(TextUtils.isEmpty(response)) {
// Show your user feedback
return;
}
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
// Check if your JSON has no elements in it
if(arr.length == 0) {
// Show your user feedback
return;
}
} catch (JSONException e1) {
e1.printStackTrace();
}
...
You have declared JSONArray arr = null;
After that you assign the server's JSON to that JSONArray.
Add a line after getting that
if(arr==null)
{
//toast
}
else
{
//whatever you want to do with JSON
}
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.POST, AppConfig.URL_Gallery4,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response.length()==0){
Toast.makeText(getActivity(),"no data found",Toast.LENGTH_SHORT).show();
}
else{
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
} catch (JSONException e1) {
e1.printStackTrace();
}
if(arr.length()>0){
int i=0;
for (i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
category = obj.getString("category_name");
selected = obj.getString("album_id");
imagename = obj.getString("org_image_name");
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
}else{
Toast.makeText(getActivity(),"no data found",Toast.LENGTH_SHORT).show();
}
}
pDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "No images in this gallery", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
};
Use the below code to check whether response is null or not and in object check whether it is having key or data with key is not null
if(response!=null){
try {
Datas.imageIds = new String[response.length()];
JSONArray arr = new JSONArray(response);
for (int i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
if(obj!=null){
if(obj.has("category_name") && !obj.isNull("category_name"){
category = obj.getString("category_name");
}
if(obj.has("album_id") && !obj.isNull("album_id"){
selected = obj.getString("album_id");
}
if(obj.has("org_image_name") && !obj.isNull("org_image_name"){
imagename = obj.getString("org_image_name");
}
if(obj.has("album_image") && !obj.isNull("album_image"){
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
pDialog.dismiss();
} catch (JSONException e1) {
e1.printStackTrace();
}
}
You are using StringRequest, instead of that use JsonArrayRequest to make request as below, so you will get response in onResponse methode when there is a valid JSONArray in response, and if there is no data then you will get response in onError method
JsonArrayRequest rReq = new JsonArrayRequest(Request.Method.GET,"url", new JSONObject(), new Response.Listener() {
#Override
public void onResponse(JSONArray response) {
Log.e(TAG, "onResponse: "+response.toString() );
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: "+error.getMessage() );
}
})