I fetch the data from my Server with Volley and put the data inside a GridView.
Now when I use swipeToRefresh, it should load the new/changed data. For this I tried everything but nothing worked.
First my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
List<getter_setter> list = new ArrayList<>();
grid_adapter grid_adapter;
GridView gridView;
SwipeRefreshLayout swipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeRefreshLayout = findViewById(R.id.swipeRefresh);
getData();
gridView = findViewById(R.id.gridView);
grid_adapter = new grid_adapter(getApplicationContext(),list);
gridView.setAdapter(grid_adapter);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
getData();
grid_adapter.update(list);
swipeRefreshLayout.setRefreshing(false);
}
});
}
public void getData(){
final String url = "http://*.**.***.***/";
final RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("userdata");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String NAME = jsonObject.getString("NAME");
String BILD = jsonObject.getString("VORSCHAUBILD");
getter_setter getter_setter = new getter_setter(NAME,"",BILD);
list.add(getter_setter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(jsonObjectRequest);
}
}
And the BaseAdapter
public class grid_adapter extends BaseAdapter{
Context context;
List<getter_setter> list;
public grid_adapter(Context context, List<getter_setter> list) {
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
public void update(List<getter_setter> listUpdate){
this.list.addAll(listUpdate);
notifyDataSetChanged();
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View gridView = view;
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
gridView = inflater.inflate(R.layout.grid_design,null);
}
final getter_setter getter = list.get(i);
TextView name = gridView.findViewById(R.id.NAME);
final ImageView bild = gridView.findViewById(R.id.bild);
name.setText(getter.getNAME());
Picasso.with(context).load(getter.getVORSCHAUBILD()).into(bild);
return gridView;
}
}
Check The Updated Listener
Explanation-:
Since You Are Passing Reference Of Your List Into RecyclerView Hence Updating List In The Activity Will Update The List In Adapter Automatically
No Need To Call update Method
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
list.clear(); // Clean The List Before Adding Updated Data
grid_adapter.notifyDataSetChanged();
getData();
grid_adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
});
Related
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.
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
I'm traying to get data from my mysql database and display them in a list view but the probleme is that the list view show only one attribut and for the others i have an error:RecyclerView: No adapter attached; skipping layout
this is my adapter :
public class DerpAdapter extends RecyclerView.Adapter<DerpAdapter.DerpHolder>{
private List<ListItem> ListData;
private LayoutInflater inflater;
private ItemClickCallback itemClickCallback;
public interface ItemClickCallback{
void onItemClick(int p);
void onSecondaryIconClick(int p);
}
public void setItemClickCallback(final ItemClickCallback itemClickCallback){
this.itemClickCallback = itemClickCallback;
}
public DerpAdapter(List<ListItem> listData, Context c){
this.inflater = LayoutInflater.from(c);
this.ListData = listData;
}
#Override
public DerpHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row,parent,false);
return new DerpHolder(view);
}
#Override
public void onBindViewHolder(DerpHolder holder, int position) {
ListItem item = ListData.get(position);
holder.title.setText(item.getTitle());
holder.subtitle.setText(item.getSubtitle());
holder.gaga.setText(item.getGaga());
}
#Override
public int getItemCount() {
return ListData.size();
}
class DerpHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView title;
private TextView subtitle;
private TextView gaga;
public DerpHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.lbl_item_text);
subtitle = (TextView) itemView.findViewById(R.id.lbl_item_sub_title);
gaga = (TextView) itemView.findViewById(R.id.gaga);
}
#Override
public void onClick(View view) {
/* if(view.getId() == R.id.cont_item_root){
}else{
}*/
}
}
this is my list item:
public class ListItem {
private String title;
private String subtitle;
private String gaga;
public String getGaga() {
return gaga;
}
public void setGaga(String gaga) {
this.gaga = gaga;
}
public ListItem(String title, String subtitle, String gaga) {
this.title = title;
this.subtitle = subtitle;
this.gaga = gaga;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getSubtitle() {
return subtitle;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
and finally this is my mainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DerpAdapter adapter;
private final String url_Data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
List<ListItem> data ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.drawarlist);
//Layout Manager: GridLayoutManager or StaggerdeGridLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
loadData();
}
public void loadData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading Data");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url_Data,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("soucat");
data = new ArrayList<>();
for (int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
ListItem item = new ListItem(o.getString("soucat"),"hello","fefe");
data.add(item);
}
adapter = new DerpAdapter(data,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
First, your initial setting of the adapter variable is commented out:
//adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
This will always set the adapter to null, you need to change it to this:
adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
Also, I don't see a call to start the Volley RequestQueue, make sure you are calling requestQueue.start(); before adding the stringRequest.
Then verify that that code for setting the adapter is being executed. You may always be hitting the ErrorListener which never sets the adapter.
You are trying to set null reference adapter to the RecyclerView, firstly you initialize adapter then set into the RecyclerView.
#Bobbake4 this is the code:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DerpAdapter adapter;
private final String url_Data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
List<ListItem> data ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.drawarlist);
//Layout Manager: GridLayoutManager or StaggerdeGridLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new DerpAdapter(DerpData.getListData(), this);
recyclerView.setAdapter(adapter);
loadData();
}
public void loadData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading Data");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url_Data,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("soucat");
data = new ArrayList<>();
for (int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
ListItem item = new ListItem(o.getString("soucat"),"hello","fefe");
data.add(item);
}
adapter = new DerpAdapter(data,getApplicationContext());
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.start();
requestQueue.add(stringRequest);
}
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);
}
}
when I conduct onRefresh, my recyclerView adds on another copy to my current recyclerView instead of refreshing it, by looking at my code below does anyone know what the problem is?I have tried everything but nothing seems to work?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
//send our volley JSON Request
//Initialize VolleySingleton
mVolleySingleton = VolleySingleton.getInstance();
//intitalize Volley Singleton request key
mRequestQueue = mVolleySingleton.getRequestQueue();
//2 types of requests an Array request and an Object Request
JSONArrayRequest();
}
private void JSONArrayRequest() {
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_API, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
listblogs=parseJSONResponse(response);
mAdapterDashBoard.setBloglist(listblogs);
System.out.println("it worked!!!");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
ToastTest.t(getActivity(), error.toString());
}
});
mRequestQueue.add(request);
}
private ArrayList<Blogs> parseJSONResponse(JSONArray response) {
if (!response.equals("")) {
ArrayList<Blogs> blogsArrayList = new ArrayList<>();
try {
StringBuilder data = new StringBuilder();
for (int i = 0; i < response.length(); i++) {
JSONObject currentQuestions = response.getJSONObject(i);
String text = currentQuestions.getString("text");
String points = currentQuestions.getString("points");
String ID=currentQuestions.getString("id");
String courseId = currentQuestions.getString("courseId");
String studentId = currentQuestions.getString("studentId");
data.append(text + "\n" + points + "\n" + courseId + "\n");
System.out.println(data);
Blogs blogs = new Blogs();
blogs.setId(ID);
blogs.setMstudentId(studentId);
blogs.setMtext(text);
blogs.setPoints(points);
listblogs.add(blogs);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return listblogs;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_dashboard,container,false);
mRecyclerView=(RecyclerView)view.findViewById(R.id.fragment_dashboard);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAdapterDashBoard=new AdapterDashBoard(getActivity());
mRecyclerView.setAdapter(mAdapterDashBoard);
mPullToRefreshView = (PullToRefreshView)view.findViewById(R.id.pull_to_refresh);
mPullToRefreshView.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {
#Override
public void onRefresh() {
mPullToRefreshView.postDelayed(new Runnable() {
#Override
public void run() {
mPullToRefreshView.setRefreshing(false);
JSONArrayRequest();
}
}, REFRESH_DELAY);
}
});
return view;
}
}
public class AdapterDashBoard extends RecyclerView.Adapter<AdapterDashBoard.ViewDashboard>{
private LayoutInflater mLayoutInflater;
private ArrayList<Blogs> listblogs=new ArrayList<>();
public AdapterDashBoard(Context context){
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<Blogs> listBlogs){
this.listblogs=listBlogs;
notifyItemRangeChanged(0,listBlogs.size());
}
#Override
public ViewDashboard onCreateViewHolder(ViewGroup parent, int viewType) {
View view= mLayoutInflater.inflate(R.layout.customizejson,parent,false);
ViewDashboard viewholder=new ViewDashboard(view);
return viewholder;
}
#Override
public void onBindViewHolder(ViewDashboard holder, int position) {
Blogs currentBlog=listblogs.get(position);
holder.questionText.setText(currentBlog.getMtext().toString());
holder.points.setText(currentBlog.getPoints().toString());
holder.id.setText(currentBlog.getId().toString());
}
#Override
public int getItemCount() {
return listblogs.size();
}
static class ViewDashboard extends RecyclerView.ViewHolder{
private ImageView thumbnail;
private TextView questionText;
private TextView points;
private TextView id;
public ViewDashboard (View itemView){
super(itemView);
//thumbnail=(ImageView)itemView.findViewById(R.id.thumbnail);
questionText=(TextView)itemView.findViewById(R.id.questionText);
points=(TextView)itemView.findViewById(R.id.points);
id=(TextView)itemView.findViewById(R.id.ID);
}
}
}
You need to clear your listblogs list before adding new items. This is why you get duplicated values.
Also you're already adding new items to listblogs in parseJSONResponse() method, so there is no need for listblogs=parseJSONResponse(response); in onResponse() method, while its the same list.
Change your onResponse() method to:
#Override
public void onResponse(JSONArray response) {
listblogs.clear(); // here you clear the old data
parseJSONResponse(response);
mAdapterDashBoard.setBloglist(listblogs);
System.out.println("it worked!!!");
}