How to refresh recyclerView after changing data - android

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.

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 can update date from adapter to recyclerView?

when I send new data or update the info, how can to change my recycle view?
I have used a dapter.notifyDataSetChanged(); , but it's not working...
I tried more method, but it all cannot change my recycler view
in my code
recyclerView = view.findViewById(R.id.recyclerCoin);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
listCoinDiamondModel = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity());
getData();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
private void sendGift(String postUserID) {
final String postUserIDD = postUserID;
final String GiftAmount = this.GiftAmount.getText().toString().trim();
final String flag = "1";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_GIFTCOIN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
if (success.equals("1")){
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),"Error" + error.toString(), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Log.d("FID", fid);
params.put("fid", fid);
params.put("GiftAmount", GiftAmount);
params.put("flag", flag);
params.put("postUserID", postUserIDD);
params.put("uid", getID);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Load...");
progressDialog.dismiss();
final String GROUP_LIST = "https://example.com/aaa.php?flag=1&fid="+ getActivity().getIntent().getStringExtra("fid") +"&page="+requestCount;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(GROUP_LIST,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), "No More gift Available", Toast.LENGTH_SHORT).show();
}
});
//Returning the request
return jsonArrayRequest;
}
//This method will get data from the web api
private void getData() {
requestQueue.add(getDataFromServer(requestCount));
requestCount++;
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the newFeedModel object
final CoinDiamondModel coinDiamondModel = new CoinDiamondModel();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
String TAG_Coin = "Coin";
String TAG_Diamond = "Diamond";
String TAG_UserName = "UserName";
String TAG_UserPhoto = "UserPhoto";
String TAG_UserID = "UserID";
//Log.d("NAME111", json.getString(json.getString(TAG_UserName)));
coinDiamondModel.setCoin(json.getString(TAG_Coin));
coinDiamondModel.setDiamond(json.getString(TAG_Diamond));
coinDiamondModel.setGiftFromUserName(json.getString(TAG_UserName));
coinDiamondModel.setGiftFromUserPhoto(json.getString(TAG_UserPhoto));
coinDiamondModel.setGiftFromUserID(json.getString(TAG_UserID));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the newFeedModel object to the list
listCoinDiamondModel.add(coinDiamondModel);
//adapter.addTheCoinData(coinDiamondModel);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
who knows what's happen and how can solve this?
could you told me how can I do, please?
adapter all code
public class CoinAdapter extends RecyclerView.Adapter<CoinAdapter.ViewHolder> {
private ImageLoader imageLoader;
private List<CoinDiamondModel> newcoinDiamondLists;
private RequestManager glide;
private Context context;
SessionManager sessionManager;
private String getID,memail;
public CoinAdapter(List<CoinDiamondModel> newcoinDiamondLists, Context context) {
this.newcoinDiamondLists = newcoinDiamondLists;
this.glide = Glide.with(context);
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.coinlist, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
sessionManager = new SessionManager(getApplicationContext());
sessionManager.checkLogin();
HashMap<String, String> user = sessionManager.getUserDetail();
getID = user.get(sessionManager.USERID);
memail = user.get(sessionManager.EMAIL);
//String gid = getIntent.getStringExtra("xxx");
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
CoinDiamondModel newCoinDiamondModel = newcoinDiamondLists.get(position);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
holder.userName.setText(newCoinDiamondModel.getGiftFromUserName());
holder.userID.setText(newCoinDiamondModel.getGiftFromUserID());
holder.coinCount.setText(" x "+newCoinDiamondModel.getCoin());
glide.load(newCoinDiamondModel.getGiftFromUserPhoto()).into(holder.userPhoto);
}
#Override
public int getItemCount() {
return newcoinDiamondLists.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
CircleImageView userPhoto;
TextView userName,userID,coinCount;
ImageView coinImg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
userPhoto = (CircleImageView) itemView.findViewById(R.id.userPhoto);
userName = (TextView) itemView.findViewById(R.id.userName);
coinCount = (TextView) itemView.findViewById(R.id.coinCount);
userID = (TextView) itemView.findViewById(R.id.userID);
coinImg = (ImageView) itemView.findViewById(R.id.coinImg);
}
}
public void addTheCoinData(CoinDiamondModel coinDiamondModel){
if(coinDiamondModel!=null){
newcoinDiamondLists.add(coinDiamondModel);
notifyDataSetChanged();
}else {
throw new IllegalArgumentException("無資料!");
}
}
}
you can again set the adapter to recycler view after the response of the server
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
}
solution 2:
in your adapter write a function to update you list
and call function in activity
add this function to the adapter
public void updateList(List<CoinDiamondModel> list){
newcoinDiamondLists = list;
notifyDataSetChanged();
}
and call a function updateList of when you need an update recyclerview
The RecyclerView initialization and notifyDataSetChanged() is used properly. As your question is not clear enough about the Adapter implementation of the RecyclerView, I can give you several suggestions to check.
In RecyclerView.Adapter check if getItemCount() method is properly overriden with returning the list length (not 0) like below:
#Override
public int getItemCount() {
return listdata.length;
}
In RecyclerView.Adapter check if onCreateViewHolder method is properly overriden with proper xml layout like below:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.coin_xml_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
In RecyclerView.Adapter check if RecyclerView.ViewHolder class is properly extended
and linked the UI elements from the xml with the adapter like below:
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView coinTextView;
public ViewHolder(View itemView) {
super(itemView);
this.coinTextView = (TextView) itemView.findViewById(R.id.coinTextView);
}
}
In RecyclerView.Adapter check if onBindViewHolder method is properly overridden and updated the list component UI properly like below:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MyListData myListData = listdata[position];
holder.cointTextView.setText(listdata[position].getCoin());
}
Debug with a breakpoint and check if the listCoinDiamondModel.add(coinDiamondModel) is calling or not and coinDiamondModel object is not empty.
The RecyclerView is placed properly in the activity xml, like the RecyclerView is Visible, has a decent size to show list elements. As an example:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
you can update your adapter list manually like this:(write this function in your adapter)
public void updateCoinAdapterList(ArrayList<listCoinDiamondModel> recyclerItemsList) {
this.recyclerItemsList = recyclerItemsList;
this.notifyDataSetChanged();
}
you must set your adapter global variable and initialize it in OnCreate or OnResume, and call
adapter.updateCoinAdapterList(listCoinDiamondModel);
when your list changed

Update database and refresh activity from another class when a card is clicked

I want that when anyone click on the CardView with Status=undone there should run an API and the database is updated and the refreshed data is loaded in RecyclerView.
This is my UpdateStatus.class having the RecyclerView data:
TextView Cid,Tno,Tname,Cono,Work;
private static final String
URL_GETDATA="";
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_status);
Bundle bundle = getIntent().getExtras();
String cid = bundle.getString("checkID");
String tno = bundle.getString("trainno");
String tname = bundle.getString("trainname");
String cno = bundle.getString("coachno");
String works = bundle.getString("work");
Cid=(TextView)findViewById(R.id.idValue);
Cid.setText(cid);
Tno=(TextView)findViewById(R.id.tnoValue);
Tno.setText(tno);
Tname=(TextView)findViewById(R.id.tnameValue);
Tname.setText(tname);
Cono=(TextView)findViewById(R.id.cnoValue);
Cono.setText(cno);
Work=(TextView)findViewById(R.id.workValue);
Work.setText(works);
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
listItems=new ArrayList<>();
loadRecyclerViewData();
}
private void loadRecyclerViewData(){
final AlertDialog dialog=new SpotsDialog(this, "Loading Data ...");
dialog.show();
StringRequest stringRequest=new StringRequest(Request.Method.POST, URL_GETDATA,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.dismiss();
Log.v("Response",response);
try {
JSONArray jsonArray=new JSONArray(response);
for (int i=0;i<jsonArray.length();i++){
ListItem item;
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.getString("status").equals("done")){
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.done
);
}else {
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.update
);
}
listItems.add(item);
}
adapter=new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() {
Bundle bundle = getIntent().getExtras();
// Posting params to login url
Map<String, String> params = new HashMap<String, String>();
params.put("checkID",bundle.getString("checkID"));
return params;
}
};
RequestQueue requestQueue= Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
This is my Adapter.class where the CardView data is loaded onClick on Card the Status is checked and An API will run using Volley and UpdateStatus activity must be refreshed with new data:
private List<ListItem> listItems;
private Context context;
private static final String
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final ListItem listItem=listItems.get(position);
holder.planned.setText(listItem.getPlanned());
holder.actual.setText(listItem.getActual());
holder.status.setImageResource(listItem.getmImageResourceid());
Intent i=new Intent(context,UpdateStatus.class);
holder.status.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(listItem.getStatus().equals("undone")){
//update code here
}
Toast.makeText(context,"You Clicked "+listItem.getStatus(),Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView planned,actual;
public ImageView status;
public LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
planned=(TextView)itemView.findViewById(R.id.planned_date);
actual=(TextView)itemView.findViewById(R.id.actual_date);
status=(ImageView)itemView.findViewById(R.id.status);
linearLayout=(LinearLayout)itemView.findViewById(R.id.linearLayout);
}
}
In OnResponse from volley when you adding a new data to your recyclerView just called a method recyclerView.notifyDataSetChanged() after recyclerView.setAdapter(adapter)
see the changes in you code below-:
#Override
public void onResponse(String response) {
dialog.dismiss();
Log.v("Response",response);
try {
JSONArray jsonArray=new JSONArray(response);
for (int i=0;i<jsonArray.length();i++){
ListItem item;
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.getString("status").equals("done")){
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.done
);
}else {
item=new ListItem(
jsonObject.getString("id"),
jsonObject.getString("checkID"),
jsonObject.getString("plannedDate"),
jsonObject.getString("actualDate"),
jsonObject.getString("status"),
R.drawable.update
);
}
listItems.add(item);
}
adapter=new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(adapter);
recyclerView.notifyDataSetChanged()
} catch (JSONException e) {
e.printStackTrace();
}
}
},
Or for better user experience you can use recyclerView.notifyItemInserted(int position) instead of recyclerView.notifyDataSetChanged(). see documentation

How to refresh listview in fragment that is filled with ArrayAdapter

I got data from json response and showed it in listView. When I delete an item in listView, it is deleted successfully but listView doesn't refresh.
I am using an ArrayAdapter instead of a BaseAdapter.
CustomList.java
public class CustomList extends ArrayAdapter<String> {
ImageButton imgdelete;
private String[] clientid;
private String[] mobile;
private String[] grand;
private String[] billid;
View listViewItem;
TextView textViewname;
private Activity context;
public CustomList(Activity context, String[] clientid, String[] mobile, String[] grand, String[] billid) {
super(context, R.layout.activity_listview, clientid);
this.context = context;
this.clientid = clientid;
this.mobile = mobile;
this.grand = grand;
this.billid = billid;
}
#Override
public View getView(final int position, final View convertView, ViewGroup parent) {
final LayoutInflater inflater = context.getLayoutInflater();
listViewItem = inflater.inflate(R.layout.activity_listview, null, true);
textViewname = (TextView) listViewItem.findViewById(R.id.viewClientMobile);
TextView textViewmobile = (TextView) listViewItem.findViewById(R.id.viewClientName);
TextView textViewgrand = (TextView) listViewItem.findViewById(R.id.viewCompnayName);
TextView textViewbillid = (TextView) listViewItem.findViewById(R.id.viewCompanyEmail);
ImageButton imgedit = (ImageButton)listViewItem.findViewById(R.id.imgeditbtn);
imgdelete = (ImageButton)listViewItem.findViewById(R.id.imgdeletebtn);
textViewname.setText(clientid[position]);
textViewmobile.setText(mobile[position]);
textViewgrand.setText(grand[position]);
textViewbillid.setText(billid[position]);
imgdelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new AlertDialog.Builder(context)
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
DeleteClient_api();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
notifyDataSetChanged();
}
});
return listViewItem;
}
protected void DeleteClient_api() {
final StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://befoodie.co/billingsystem/client_api.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Toast.makeText(getContext(), response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
// final String session = ActivityLogin.MostSecureRandom.nextSessionId();
params.put("Action", "RemoveClient");
params.put("ClientID",textViewname.getText().toString());
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(stringRequest);
}
}
ViewAllClient.java
public class ViewAllClient extends Fragment {
private ListView listView;
//create Array of product Details
public ViewAllClient() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_view_all_client, container, false);
// listView = (ListView) rootView.findViewById(R.id.listviewclient);
listView = (ListView) rootView.findViewById(R.id.listviewclient);
View_api();
return rootView;
}
protected void View_api(){
final StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://befoodie.co/billingsystem/client_api.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response); //Toast.makeText(getActivity(), response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
// final String session = ActivityLogin.MostSecureRandom.nextSessionId();
params.put("Action", "ViewClients");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
protected void showJSON(String json){
ParseJSON pj = new ParseJSON(json);
pj.parseJSON();
final CustomList cl = new CustomList(getActivity(), ParseJSON.CLIENTID,ParseJSON.mobile,ParseJSON.grand, ParseJSON.billid);
listView.setAdapter(cl);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
}
ParseJSON.java
public class ParseJSON {
public static String[] CLIENTID;
public static String[] mobile;
public static String[] grand;
public static String[] billid;
public static final String JSON_ARRAY = "ClientDetails";
public static final String KEY_ID = "ClientID";
public static final String KEY_MOBILE = "ClientName";
public static final String KEY_GRAND = "EmailID";
public static final String KEY_BILL = "StartingCommunicationDate";
private JSONArray users = null;
private String json;
public ParseJSON(String json){
this.json = json;
}
protected void parseJSON(){
JSONObject jsonObject=null;
try {
jsonObject = new JSONObject(json);
users = jsonObject.getJSONArray(JSON_ARRAY);
CLIENTID = new String[users.length()];
mobile = new String[users.length()];
grand = new String[users.length()];
billid = new String[users.length()];
for(int i=0;i<users.length();i++){
JSONObject jo = users.getJSONObject(i);
CLIENTID[i] = jo.getString(KEY_ID);
mobile[i] = jo.getString(KEY_MOBILE);
grand[i] = jo.getString(KEY_GRAND);
billid[i] = jo.getString(KEY_BILL);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Call adapter.notifyDataSetChanged() on your Adapter object once you've modified the data in that adapter. ;
Note : For an ArrayAdapter, notifyDataSetChanged only works if you use the add(), insert(), remove(), and clear() on the Adapter.
Try below code,
YourAdapter adapter = new YourAdapter(context, ListDataHeader, ListDataChild, data);
adapter.notifyDataSetChanged();
Hi #Dipu First you have to delete the item from the local jsonresponse(which is populating your list).After that you have to notify the adapter that the data has been changed.If you deleted from inside the adapter simply write notifyDataSetChanged(); after deleting the item.
If you are deleting from the class then you have to simply write
adapter.notifyDataSetChanged();
I hope it helps
// in ViewAllClient fragment
public void delete(int position){
adapter.notifyItemChanged(position);//-- only update the required row
// notifyDataSetChanged for full listview
}
// in adapter
ViewAllClient viewAllClient =new ViewAllClient();
viewAllClient .delete(position);

use same recyclerview adapter with different layout

I've a recyclerview adapter with 3 textviews. I used a model class to set texts. Now I want to use the same adapter with different layout and in a different class which only have 1 textview. When I tried, I got NullPointerException (may be becuz the other 2 textviews are blank). Is there any way to use same adapter with different layout and in different class?
// second class - I used 1 textview
public class Customers extends AppCompatActivity{
private CShowProgress cShowProgress;
private RecyclerView mRecyclerView;
private TimeLineAdapter mTimeLineAdapter;
private List<TimeLineModel> mDataList = new ArrayList<>();
private static final String CUSTOMERS = "http://192.168.200.3/ubooktoday/android/showspacustomerlist";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customers);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
cShowProgress = CShowProgress.getInstance();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(getLinearLayoutManager());
mRecyclerView.setHasFixedSize(true);
showCustomers();
}
private void showCustomers() {
if(mDataList!=null )mDataList.clear();
cShowProgress.showProgress(Customers.this);
StringRequest stringRequest = new StringRequest(Request.Method.POST, CUSTOMERS,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
cShowProgress.hideProgress();
try {
JSONArray jsonArray = new JSONArray(response);
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
TimeLineModel model = new TimeLineModel();
model.setCustname(obj.getString("customername"));
mDataList.add(model);
mTimeLineAdapter = new TimeLineAdapter(getApplicationContext(), R.layout.item_row_customer, mDataList);
mRecyclerView.setAdapter(mTimeLineAdapter);
}
mTimeLineAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
private LinearLayoutManager getLinearLayoutManager() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
return linearLayoutManager;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
}
// first class - I used all 3 textviews
public class Walkin extends Fragment{
private RecyclerView mRecyclerView;
private TimeLineAdapter mTimeLineAdapter;
private List<TimeLineModel> mDataList = new ArrayList<>();
private static final String DASHBOARD = "My API";
#Nullable
#Override
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.walkin, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(getLinearLayoutManager());
mRecyclerView.setHasFixedSize(true);
showDashboard();
}
private void showDashboard() {
if(mDataList!=null )mDataList.clear();
cShowProgress.showProgress(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.POST, DASHBOARD,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("walkinlist");
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
TimeLineModel model = new TimeLineModel();
model.setCustname(obj.getString("customername"));
model.setTime(obj.getString("serviceDuration"));
model.setServname(obj.getString("service"));
mDataList.add(model);
mTimeLineAdapter = new TimeLineAdapter(getActivity(), R.layout.item_row_dashboard, mDataList);
mRecyclerView.setAdapter(mTimeLineAdapter);
}
mTimeLineAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
private LinearLayoutManager getLinearLayoutManager() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
return linearLayoutManager;
}
}
// Adapter class
public class TimeLineAdapter extends RecyclerView.Adapter<TimeLineViewHolder> {
private List<TimeLineModel> mFeedList;
int resource;
private Context mContext;
public TimeLineAdapter(Context mContext, int resource, List<TimeLineModel> feedList) {
this.resource = resource;
this.mContext = mContext;
mFeedList = feedList;
}
#Override
public TimeLineViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder(view, viewType);
}
#Override
public void onBindViewHolder(TimeLineViewHolder holder, int position) {
TimeLineModel timeLineModel = mFeedList.get(position);
holder.servicename.setText(timeLineModel.getServname());
holder.custname.setText(timeLineModel.getCustname());
holder.time.setText(timeLineModel.getTime());
}
#Override
public int getItemCount() {
return (mFeedList!=null? mFeedList.size():0);
}
}
// ViewHolder class
public class TimeLineViewHolder extends RecyclerView.ViewHolder {
public TextView servicename, custname, time;
public TimeLineViewHolder(View itemView, int viewType) {
super(itemView);
servicename = (TextView) itemView.findViewById(R.id.tv_service);
custname = (TextView) itemView.findViewById(R.id.tv_cust);
time = (TextView) itemView.findViewById(R.id.tv_time);
}
}
You can use the getItemViewType().
Make your adapter(here TimeLineAdapter) extend RecyclerView.Adapter only.
You can change the Adapter's constructer to recieve ItemType and use it in the getItemViewType
Override the int getItemViewType (int position) method in your adapter.
In the onCreateViewHolder you can differentiate between which layout you want to inflate by using the viewType parameter.
In onBindViewHolder use instanceof to check which ViewHolder was created and call the related bind functions
A Sample Code-
// Adapter class
public class TimeLineAdapter extends RecyclerView.Adapter{
.....
int type;
public TimeLineAdapter(Context mContext, int resource, List<TimeLineModel> feedList,int layoutType) {
.....
.....
type=layoutType;
}
#Override
public int getItemViewType(int position) {
return type;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==1){
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder(view, viewType);
}else{
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder2(view, viewType);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof TimeLineViewHolder){
TimeLineModel timeLineModel = mFeedList.get(position);
((TimeLineViewHolder) holder).servicename.setText(timeLineModel.getServname());
......
}
else if(holder instanceof TimeLineViewHolder2){
....
....
}
}
#Override
public int getItemCount() {
return (mFeedList!=null? mFeedList.size():0);
}
}

Categories

Resources