pull refresh error keep adding every time i pull - android

I trying to create a pull refresh.
every time I pull it.
Here's my code:
public class LatestGradeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
List<ListGradeData> sectionList;
RecyclerView recyclerView;
SwipeRefreshLayout mSwipeRefreshLayout;
public static LatestGradeFragment newInstance() {
return new LatestGradeFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_latest_grade, container, false);
//RecyclerView+CardView for section
recyclerView = (RecyclerView) rootView.findViewById(R.id.display_recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
sectionList = new ArrayList<>();
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeRefreshSection);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary,
android.R.color.holo_green_dark,
android.R.color.holo_orange_dark,
android.R.color.holo_blue_dark);
mSwipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
// Fetching data from server
loadSection();
}
});
return rootView;
}
#Override
public void onRefresh() {
loadSection();
}
private void loadSection() {
mSwipeRefreshLayout.setRefreshing(true);
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.USER_GRADE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject sections = array.getJSONObject(i);
//adding the product to product list
sectionList.add(new ListGradeData(
sections.getInt("id"),
sections.getString("section"),
sections.getString("level"),
sections.getString("schoolyear")
));
}
//creating adapter object and setting it to recyclerview
LatestGradeAdapter adapter = new LatestGradeAdapter(getActivity(), sectionList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
// Stopping swipe refresh
mSwipeRefreshLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Stopping swipe refresh
mSwipeRefreshLayout.setRefreshing(false);
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(getActivity().getApplicationContext()).add(stringRequest);
}
#Override
public String toString() {
return "LatestGradeFragment ";
}
}
I'm new in android/java could anyone help me.

Inside respone of api you have to clear list first, so it will never repeat data. Your code inside response inside try block should be:
if(sectionList!=null) {
sectionlist.clear();
}

remove this part, its unnecessary
mSwipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
// Fetching data from server
loadSection();
}
});
and you should create LatestGradeAdapter as globe variable, just notify data change whenever you get new data from server

Related

Nested Recycler Adapter Items going into the wrong Recycler Views

On my app, I have a Recyler View with multiple recycler views inside. The inner recycler views are inserted dynamically. The issue Im having is that some items from some inner recycler views are going to other inner recycler views where there should be no items, like in the image below.
The top recycler view should not have those items while the bottom one is correct. I noticed that the items always glitch on the same recycler views, and after debugging I also noticed that on the glitched views, it doesnt even enter the sub adapter which makes it even weirder.
I should also mention that the sub recycler views are inserted based on volley requests. I make a request to an API and it generates the items. I have also checked and the API is giving the right response.
Fragment code (where the main recycler view is called):
RequestQueue requestQueue;
String URL;
RecyclerView catList;
CategoriesMainRecycleAdapter adapter;
List<String> cats;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_categories, container, false);
catList = v.findViewById(R.id.crv_main_categories);
cats = new ArrayList<>();
URL = /*Removed this part for privacy reasons*/;
Submit();
// Inflate the layout for this fragment
return v;
}
private void Submit()
{
requestQueue = Volley.newRequestQueue(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject cat = jsonArray.getJSONObject(i);
String a;
a = cat.getString("mCategoryName");
cats.add(a);
}
if (getActivity()!=null) {
adapter = new CategoriesMainRecycleAdapter(getActivity(), cats, (String) getText(R.string.website_link));
catList.setLayoutManager(new LinearLayoutManager(getActivity()));
catList.setAdapter(adapter);
}
} catch (JSONException e) {
Toast.makeText(getContext(), R.string.login_communication_error, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), R.string.login_communication_error, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
});
requestQueue.add(stringRequest);
}
Main Recycler Adapter Code (this is where the sub adapter are called):
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.title.setText(capitalizeLetters(mCats.get(position)));
holder.viewAll.setImageResource(R.drawable.ic_baseline_arrow_forward_24_black);
holder.lbl_error.setText(R.string.no_anime_with_category_error);
holder.lbl_error.setVisibility(View.INVISIBLE);
holder.viewAll.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.image_click));
Intent i = new Intent(mContext, anime_category.class);
i.putExtra("Category", mCats.get(position));
mContext.startActivity(i);
}
}
);
//Start the other recycler views
URL = /*Removed for privacy reasons*/;
String data = "{"+
"\"mCategoryName\":" + "\"" + mCats.get(position) + "\"" +
"}";
Submit(data, holder);
}
private void Submit(String data, ViewHolder holder)
{
final String savedata= data;
requestQueue = Volley.newRequestQueue(Objects.requireNonNull(mContext));
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
holder.lbl_error.setVisibility(View.INVISIBLE);
List<anime_class> animes = new ArrayList<>();
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject anime = jsonArray.getJSONObject(i);
anime_class a = new anime_class();
a.setmNameEN(anime.getString("mNameEN"));
a.setmNameJP(anime.getString("mNameJP"));
a.setmDescription(anime.getString("mDescription"));
a.setmThumbnail(anime.getString("mThumbnail"));
a.setmEpisodeCount(anime.getInt("mEpisodeCount"));
a.setmOnGoing(anime.getBoolean("mOnGoing"));
//Add Categories
List<String> cats = new ArrayList<>();
JSONArray catArray = anime.getJSONArray("mCategories");
for (int i2 = 0; i2 < catArray.length(); i2++)
{
cats.add(catArray.get(i2).toString());
}
a.setmCategories(cats);
animes.add(a);
}
if (mContext!=null) {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
holder.rcv.getContext(),
LinearLayoutManager.HORIZONTAL,
false
);
linearLayoutManager.setInitialPrefetchItemCount(animes.size());
CategoriesSubRecycleAdapter adapter = new CategoriesSubRecycleAdapter(mContext, animes);
holder.rcv.setLayoutManager(linearLayoutManager);
holder.rcv.setAdapter(adapter);
holder.rcv.setRecycledViewPool(catAnime);
}
} catch (JSONException e) {
Toast.makeText(mContext, R.string.login_communication_error, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(error.networkResponse.statusCode == 404)
{
holder.lbl_error.setVisibility(View.VISIBLE);
}
else
Toast.makeText(mContext, R.string.login_communication_error, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
return savedata == null ? null : savedata.getBytes(StandardCharsets.UTF_8);
}
};
requestQueue.add(stringRequest);
}
Sub recycler adapter (this part seems to work fine based on some debugging I did):
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.title.setText(capitalizeLetters(mAnime.get(position).getmNameEN()));
Glide.with(mContext).load(mAnime.get(position).getmThumbnail()).into(holder.thumbnail);
holder.crv_.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, anime_page.class);
i.putExtra("mNameEN", mAnime.get(position).getmNameEN());
i.putExtra("mThumbnail", mAnime.get(position).getmThumbnail());
mContext.startActivity(i);
}
}
);
}
I found a trick that fixes the problem, but I dont believe its very optimized. On the Main Recycler Adapter, when I call the Submit method to get the data from the request, on the onErrorResponse I add 0 items, by creating an empty List and giving it to the adapter.
#Override
public void onErrorResponse(VolleyError error) {
if(error.networkResponse.statusCode == 404)
{
List<anime_class> animes = new ArrayList<>();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
holder.rcv.getContext(),
LinearLayoutManager.HORIZONTAL,
false
);
linearLayoutManager.setInitialPrefetchItemCount(animes.size());
CategoriesSubRecycleAdapter adapter = new CategoriesSubRecycleAdapter(mContext, animes);
holder.rcv.setLayoutManager(linearLayoutManager);
holder.rcv.setAdapter(adapter);
holder.rcv.getRecycledViewPool().clear();
holder.rcv.setRecycledViewPool(catAnime);
holder.rcv.setNestedScrollingEnabled(false);
adapter.notifyDataSetChanged();
holder.lbl_error.setVisibility(View.VISIBLE);
}
else
Toast.makeText(mContext, R.string.login_communication_error, Toast.LENGTH_SHORT).show();
error.printStackTrace();

How to refresh recyclerView after changing data

I am working on developing an application that contains (recyclerView ) display member responses.I have a problem after a member posts a new comment the (recyclerView ) is not updated in real time.
How can I update the data (recyclerView ) after entering new data without the user exiting or closing the application؟
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<List_Data>list_data;
public MyAdapter(List<List_Data> list_data) {
this.list_data = list_data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_data,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
List_Data listData=list_data.get(position);
holder.txtname.setText(listData.gettext());
holder.txtmovie.setText(listData.getmovie_id());
}
#Override
public int getItemCount() {
return list_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView txtname,txtmovie,ImageView;
public ViewHolder(View itemView) {
super(itemView);
txtname=(TextView)itemView.findViewById(R.id.txt_name);
txtmovie=(TextView)itemView.findViewById(R.id.txt_moviename);
}
}
}
public class StatusFragment extends Fragment {
Button btn_send_comment;
EditText ETXT_comment;
String id;
private List<List_Data> list;
private RecyclerView rvy;
private MyAdapter adapter;
ImageView btn_add_comments;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.status, container, false);
ETXT_comment = (EditText)rootView.findViewById(R.id.ETXT_comment);
btn_add_comments = (ImageView) rootView.findViewById(R.id.btn_add_comments);
btn_send_comment = (Button) rootView.findViewById(R.id.btn_send_comment);
Intent i = getActivity().getIntent();
final String movie_id = i.getStringExtra("id");
rvy=(RecyclerView)rootView.findViewById(R.id.recyclerview);
rvy.setHasFixedSize(true);
rvy.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
list=new ArrayList<>();
adapter=new MyAdapter(list);
getComment(movie_id);
//----------------Send Commant
btn_send_comment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String comment_text = ETXT_comment.getText().toString().trim();
if (comment_text.equals("")) {
} else {
//
final String REGISTER_URL = "http://0000000/Comment.php";
StringRequest stringRequest = new StringRequest(Request.Method.POST, REGISTER_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// getComment(movie_id);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity().getApplicationContext(), error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
params.put("comment", comment_text);
return params;
}
};
RequestQueue requestQueue = (RequestQueue) Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(stringRequest);
}
}
});
//--------------------
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void getComment(String id){
final String HI ="http://0000000/Cm.php?id=" + id ;
StringRequest stringRequest=new StringRequest(Request.Method.GET, HI, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject=new JSONObject(response);
JSONArray array=jsonObject.getJSONArray("info");
for (int i=0; i<array.length(); i++ ){
JSONObject ob=array.getJSONObject(i);
List_Data listD=new List_Data(ob.getString("comment")
,ob.getString("name"));
list.add(listD);
// adapter.notifyItemRangeChanged(0, list_data.size());
// rv.removeAllViews();
}
rvy.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(stringRequest);
}
}
Also whene I put getComment(movie_id); into onResponse it's work but there are other problem it's show data Repeats in two times For each comment from user.
Did you try to add new comment into your list and then call the statement
adapter.notifyDataSetChanged()
Move rvy.setAdapter(adapter) from getComment() to onViewCreated()
Clear the list at the start of your getComment() method, add this line:
list.clear()
In your code, you appended the same items to this instance of List when you call .add(), hence, repeated elements appear.
After list.add(listD), call adapter.notifyDataSetChanged()
When you return a new comment, you didn't add the RecyclerView adapter list with the new comment. What you just did is updating the fragment list with the new comment, and the adapter has no idea about this list update.
So, modify you adapter to accept a new comment method and update the list with just the new inserted row using notifyItemInserted():
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<List_Data>list_data;
public MyAdapter(List<List_Data> list_data) {
this.list_data = list_data;
}
public addComment(List_Data comment) {
this.list_data.add(comment);
notifyItemInserted(list_data.size() - 1); // Updating adapter list
}
// ... rest of code
}
And in your getComment() use the new added adapter method when you get the response.
Notice the change in // <<<<<<<<<<<<<<<< Updating adapter list
private void getComment(String id){
final String HI ="http://0000000/Cm.php?id=" + id ;
StringRequest stringRequest=new StringRequest(Request.Method.GET, HI, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject=new JSONObject(response);
JSONArray array=jsonObject.getJSONArray("info");
for (int i=0; i<array.length(); i++ ){
JSONObject ob=array.getJSONObject(i);
List_Data listD = new List_Data(ob.getString("comment")
,ob.getString("name"));
list.add(listD);
adapter.addComment(listD); // <<<<<<<<<<<<<<<< Updating adapter list
// rv.removeAllViews();
}
rvy.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(stringRequest);
}
finally don't forget to uncomment the usage of the getComment() within the btn_send_comment button listener.

Synchronous Call in Fragment didn't run at first launch and get error data

I am using OkHttp to get HTML string and list the information in RecyclerView in a fragment.
However, when the app runs, it didn't show list information at first launch.
After I click other fragment page and go back to this fragment page, it show list.
But when I swipe down to see more list, the list repeat for twice (or more?) and the item background color disordered.
How can I fix it? Thanks!
My Adapter
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private List<NewsModel> mNewsList;
class ViewHolder extends RecyclerView.ViewHolder {
TextView newsNameText;
TextView newsDataText;
View listView;
public ViewHolder(View newsView) {
super(newsView);
newsNameText = (TextView) newsView.findViewById(R.id.news_Name);
newsDataText = (TextView) newsView.findViewById(R.id.news_Data);
listView = newsView;
}
}
public NewsAdapter(List<NewsModel> newsList) {
mNewsList = newsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
return holder;
}
public void setData(List<NewsModel> viewData) {
mNewsList.clear();
mNewsList.addAll(viewData);
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
NewsModel news = mNewsList.get(position);
holder.setIsRecyclable(true);
if(position % 2 == 0){
holder.listView.setBackgroundColor(0x80E0EEEE);
}
holder.newsNameText.setText(news.getName());
holder.newsDataText.setText(news.getData());
}
#Override
public int getItemCount() {
return mNewsList.size();
}
}
My fragment
public class NewsFragment extends Fragment {
List<NewsModel> resultList = new ArrayList<>();
List<NewsModel> htmlList = new ArrayList<>();
NewsAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
adapter = new NewsAdapter(getNews());
newsRecyclerView.setAdapter(adapter);
return newsView;
}
private List<NewsModel> getNews() {
new Thread(new Runnable() {
#Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = client.newCall(request).execute();
String resultString = response.body().string();
resultList.clear();
resultList.addAll(getResult(resultString));
adapter.notifyDataSetChanged();
/*new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
adapter.setData(resultList);
adapter.notifyDataSetChanged();
}
});//postdelayed (runnable long) cannot be applied to runnable*/
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return resultList;
}
private List<NewsModel> getResult(final String response) {
XXXXXX
return htmlList;
}
}
The problem is that maybe you are adding many entries and since recyclerview is trying to reuse those views instead of redrawing again and again which cause sometimes view inconsistency. Here is the problem discussed Look into it if you are having the same problem.
to disable it or enable it to use in your bindViewHolder()
setIsRecyclable(Boolean enable)
And your second problem is that onCreateView() is called the second time when coming back from another fragment causing addition of duplicate data again so you need to clear the list before adding any new entries and Why it's not showing in the first run because you have added data in another thread and did not updated the adapter about it.
List<NewsModel> resultList = new ArrayList<>();
NewsAdapter adapter ;
public class NewsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
adapter = new NewsAdapter(resultList);
newsRecyclerView.setAdapter(adapter);
getNews();
return newsView;
}
private void getNews(){
AsyncTask<Void,Void,String> asyncTask = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(final Void... voids) {
String resultString = null;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = null;
try {
response = client.newCall(request).execute();
resultString = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return resultString;
}
#Override
protected void onPostExecute(final String resultString) {
super.onPostExecute(resultString);
resultList.clear();
resultList.addAll(getResult(resultString));
adapter.notifyDataSetChanged();
}
}.execute();
}
The thread will change the resultList in some delay, but you already passed old data before that.
Please try as following...
public class NewsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
getNews(newsRecyclerView);
return newsView;
}
private void getNews(final RecyclerView newsRecyclerView){
new Thread(new Runnable() {
#Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = client.newCall(request).execute();
String resultString = response.body().string();
List<NewsModel> resultList = getResult(resultString);
NewsAdapter adapter = new NewsAdapter(resultList);
newsRecyclerView.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private List<NewsModel> getResult(final String response) {
XXXXXXXXX
return List;
}
Main pattern is bad.
The easiest way for this code is to set (not add) items in adapter when it is downloaded and invoke on adapter notifyDataSetChanged() - all cells will be redraw.
So make adapter as field, add method to adapter setData() and:
...
Response response = client.newCall(request).execute();
String resultString = response.body().string();
resultList = getResult(resultString);
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
adapter.setData(results);
adapter.notifyDataSetChanged();
}
});

I have fetched data in Android by using PHP Web services it fetched but when new data is added it can't fetched?

By using below code I am fetching data. When I run it the first time it will show all data. When I insert new data it will be inserted successfully but on going to report page and clicking on that it shows previous data and not the new or updated data.
public class Fragment_Emp_Report extends Fragment {
List<Get_EmpNameAdapter> get_empNameAdapter1;
RecyclerView recyclerView;
ProgressBar progressBar;
RecyclerView.LayoutManager recyclerViewlayoutManager;
RecyclerView.Adapter recyclerViewadapter;
String url = "http://ghawadediilip.000webhostapp.com/Services/jsonFetchName.php";
String JSON_NAME = "emp_name";
JsonArrayRequest jsonArrayRequest;
RequestQueue requestQueue;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_emp_report,container,false);
fetchEmpName();
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
get_empNameAdapter1 = new ArrayList<>();
recyclerView = (RecyclerView)view.findViewById(R.id.report_recyclerview);
recyclerView.setHasFixedSize(true);
recyclerViewlayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(recyclerViewlayoutManager);
}
public void fetchEmpName()
{
jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
jsonFetch(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(jsonArrayRequest);
RequestQueue.RequestFinishedListener listener = new RequestQueue.RequestFinishedListener() {
#Override
public void onRequestFinished(Request request) {
recyclerViewadapter.notifyDataSetChanged();
}
};
requestQueue.addRequestFinishedListener(listener);
}
public void jsonFetch(JSONArray array)
{
for (int i=0;i<array.length();i++)
{
Get_EmpNameAdapter get_empNameAdapter2 = new Get_EmpNameAdapter();
JSONObject json=null;
try {
json = array.getJSONObject(i);
get_empNameAdapter2.setEmpname(json.getString(JSON_NAME));
} catch (JSONException e) {
e.printStackTrace();
}
recyclerView.setAdapter(recyclerViewadapter);
get_empNameAdapter1.add(get_empNameAdapter2);
}
recyclerViewadapter = new Report_Recyclerview_Adapter(get_empNameAdapter1,getContext());
recyclerView.setAdapter(recyclerViewadapter);
}
}
Your fetchEmpName(); called only one time when onCreateView is called if you want to refetch the date when back from another fragment then you have to call your method again you can achieve that by calling it in onResume.

Webservices with Retained Fragments

I have a Fragment that is used to retrieve some data from my CMS with the help of the Volley lib. I am using RecyclerViews to do that. It works. However when I am rotating the screen,the webservice is run again. How can I stop that? I tried to use **setRetainInstance(true); but at no vail. From what I have read,this method bypasses the onDestroy() fragment's method,and hence the onCreate() fragment's method is not called when you rotate the screen. If I am wrong with that please correct me. Here is my code.
FeaturesActivity
public class FeaturesActivity extends AppCompatActivity {
private static final String FEATURES_FRAGMENT = "Features_fragment";
FeaturesFragment ff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_features);
FragmentManager fragmentManager = getSupportFragmentManager();
ff = (FeaturesFragment) fragmentManager.findFragmentByTag(FEATURES_FRAGMENT);
if(ff == null) {
ff = new FeaturesFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(android.R.id.content, ff);
fragmentTransaction.commit();
}
}
}
And the actual fragment itself.
public class FeaturesFragment extends Fragment {
public static final String TAG = "ManuApp";
private static final String IMAGE_URL = "http://xxx/xxx/features_images/" ;
private List<FeaturesObject> listItemsList;
private RecyclerView mRecyclerView;
private FeaturesAdapter adapter;
public FeaturesFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
Log.v("retained","oncreate called");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_features, container, false);
// Inflate the layout for this fragment
listItemsList = new ArrayList<>();
mRecyclerView = (RecyclerView)v.findViewById(R.id.features_recycler_view);
//mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).color(Color.BLACK).build());
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
updateFeaturesList();
}
public void updateFeaturesList() {
//declare the adapter and attach it to the recyclerview
adapter = new FeaturesAdapter(getActivity(), listItemsList);
mRecyclerView.setAdapter(adapter);
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(getActivity());
// Request a string response from the provided URL.
JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, Config.URL_FEATURES, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
//hidePD();
// Parse json data.
// Declare the json objects that we need and then for loop through the children array.
// Do the json parse in a try catch block to catch the exceptions
try {
for (int i = 0; i < response.length(); i++) {
JSONObject post = response.getJSONObject(i);
FeaturesObject item = new FeaturesObject();
item.setTitle(post.getString("title"));
item.setImage(IMAGE_URL + post.getString("features_image"));
item.setArticle(post.getString("article"));
listItemsList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
// Update list by notifying the adapter of changes
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
//hidePD();
}
});
queue.add(jsObjRequest);
}
}
I logged out a message inside the onCreate(...),but it is called even if I rotate the screen. How can I fix that?
Thanks.
I fixed it using the following code inside the manifest.xml file
android:configChanges="screenSize|orientation"
Google though states that we should use that as a resourse.

Categories

Resources