i'm tyring to get some informations from Tumblr blogs using Tumblr API ,now i'm tyring to get Name (blog_name) and Image Cover (Header_image) from Json below
Json Tree Picture
my code below works fine but when i set Name and ImageCover into TextView and ImageView something weird happening ,i find name of first blog in 3rd recyclview item or 4th the same thing for Image cover, also when
i scroll top to bottom of recyclview the name and image change randomly i do not know why.
here's myAdapterTumblr.java ,and
sorry if I dont explain well
public class myAdapterTumblr extends RecyclerView.Adapter<myAdapterTumblr.ViewHolder> {
RequestQueue requestQueue;
TextView name;
private List<PostTumblr> postTumblrs;
private Context context;
private RecyclerViewClickListenerTumblr mClickListener;
private String APIKey = "";
public myAdapterTumblr(List<PostTumblr> postTumblrs, Context context, RecyclerViewClickListenerTumblr clickListener) {
this.postTumblrs = postTumblrs;
this.context = context;
this.mClickListener = clickListener;
}
public List<PostTumblr> getItems() {
return postTumblrs;
}
#Override
public myAdapterTumblr.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.tumblr_profil,
parent, false);
return new myAdapterTumblr.ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bindModel(postTumblrs.get(position));
}
#Override
public int getItemCount() {
return postTumblrs.size();
}
public void getJsonDataCover(PostTumblr mPost, final RequestOptions options, final ProgressBar progressBarCover, final ImageView imgcover) {
String jsonStr = "https://api.tumblr.com/v2/blog/" + mPost.getTumblrname() + ".tumblr.com/posts/photo?api_key=" + APIKey;
final StringRequest stringRequest = new StringRequest(Request.Method.GET, jsonStr, new Response.Listener<String>() {
#SuppressLint("CheckResult")
#Override
public void onResponse(String s) {
try {
String cover = null;
JSONObject obj = new JSONObject(s);
JSONObject response = obj.getJSONObject("response");
JSONArray posts = response.getJSONArray("posts");
for (int i = 0; i < posts.length(); ++i) {
JSONObject post = posts.getJSONObject(i);
JSONArray trail = post.getJSONArray("trail");
for (int j = 0; j < trail.length(); ++j) {
JSONObject trailobj = trail.getJSONObject(j);
JSONObject blog = trailobj.getJSONObject("blog");
JSONObject theme = blog.getJSONObject("theme");
cover = theme.getString("header_image");
Glide.with(context).asBitmap()
.load(cover)
.apply(options)
.listener(new RequestListener<Bitmap>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
progressBarCover.setVisibility(View.GONE);
return false;
}
}).into(imgcover);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue.add(stringRequest);
}
private void getJsonDataText(PostTumblr mPost, final TextView nametv) {
String jsonStr = "https://api.tumblr.com/v2/blog/" + mPost.getTumblrname() + ".tumblr.com/posts/photo?api_key=" + APIKey;
final StringRequest stringRequest = new StringRequest(Request.Method.GET, jsonStr, new Response.Listener<String>() {
#SuppressLint("CheckResult")
#Override
public void onResponse(String s) {
try {
JSONObject obj = new JSONObject(s);
JSONObject response = obj.getJSONObject("response");
JSONArray posts = response.getJSONArray("posts");
String name = null;
for (int i = 0; i < posts.length(); ++i) {
JSONObject post = posts.getJSONObject(i);
name = post.getString("blog_name");
}
nametv.setText(name);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue.add(stringRequest);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
PostTumblr mPost;
ImageView image, imgcover;
ProgressBar progressBarProfile, progressBarCover;
TextView facebooktv;
TextView instagramtv;
TextView siettv;
ViewHolder(View v) {
super(v);
image = itemView.findViewById(R.id.profilepic);
imgcover = itemView.findViewById(R.id.coverpic);
progressBarProfile = itemView.findViewById(R.id.progressprofile);
progressBarCover = itemView.findViewById(R.id.progresscover);
requestQueue = Volley.newRequestQueue(context);
name = itemView.findViewById(R.id.name);
facebooktv = itemView.findViewById(R.id.fb);
instagramtv = itemView.findViewById(R.id.instagram);
siettv = itemView.findViewById(R.id.tumblr);
progressBarProfile.getIndeterminateDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY);
progressBarCover.getIndeterminateDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY);
v.setOnClickListener(this);
}
#SuppressLint("CheckResult")
void bindModel(final PostTumblr postTumblr) {
/*profil*/
this.mPost = postTumblr;
final RequestOptions options = new RequestOptions();
options.diskCacheStrategy(DiskCacheStrategy.ALL)
.priority(Priority.HIGH)
.dontAnimate()
.dontTransform();
Glide.with(context).asBitmap()
.load("https://api.tumblr.com/v2/blog/" + postTumblr.getTumblrname() + ".tumblr.com/avatar/512")
.apply(options)
.listener(new RequestListener<Bitmap>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
progressBarProfile.setVisibility(View.GONE);
return false;
}
}).into(image);
getJsonDataText(mPost, name);
getJsonDataCover(mPost, options, progressBarCover, imgcover);
facebooktv.setText(mPost.getTumblrname());
instagramtv.setText(mPost.getTumblrname());
siettv.setText(mPost.getTumblrname() + ".tumblr.com");
}
#Override
public void onClick(View view) {
mClickListener.onClick(view, mPost);
}
}
}
You are misplacing code implementation of data-fetching.
RecyclerView (as its name comes with it) reuse the views it creates, so when the data is being fetched asynchronously after a while the view may not belong to the data that have been fetched.
To solve the problem you should move data-fetching codes outside the myAdapterTumblr codes, and once all the data have been fetched set the data into the adapter and call notifyDataSetChanged() method of the adapter.
Related
I am having this issue for some time now, when I retrieved data from a database using volley and then show it in a recycler view, if the items are 8 or less than 8 then it shows them without any problem, but if I retrieve more than 8 items from database then the activity closes/crashes and goes back to the main activity. I don't get any error in the run console in android studio. I am retrieving 3 things from database for a single item, 2 strings and an image. I don't think the error is in the php file which is used to get the data as that I have checked and it retrieves without any issue. I have searched android documentation of recycler view but couldn't find anything
NOTE: I am getting image as string and then converting to bitmap.
if there is anything else needed then I can provide them without any issue.
the code is below:
Method which is used to call the recycler view activity which has problems.
public void onViewAttendanceButtonClick(int position, String courseCode,
String courseName, String batchName) {
if (MainActivity.teacherData != null) {
seeAttendanceDetails(MainActivity.teacherData.getEmail(),courseCode,
batchName, courseName, getDateAndTime);
}
}
private void seeAttendanceDetails(final String email,final String
courseCode, final String batchName,final String courseName, final String
date) {
StringRequest stringRequest = new StringRequest(Request.Method.POST,
seeAttendanceDetails, 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 data = jsonArray.getJSONObject(i);
String fullName = data.getString("full_name");
String Email = data.getString("email");
String photo = data.getString("photo");
Toast.makeText(CoursesActivity.this, courseCode,
Toast.LENGTH_LONG).show();
Attendance attendance1 = new Attendance(fullName, Email, photo);
attendanceArrayList.add(attendance1);
}
if (!attendanceArrayList.isEmpty()) {
Intent intent = new Intent(CoursesActivity.this,
ShowAttendanceActivity.class);
Bundle bundle = new Bundle();
bundle.putString("attendanceCourseCode",
courseCode);
bundle.putString("attendanceCourseName",
courseName);
bundle.putString("attendanceBatchName", batchName);
bundle.putSerializable("attendanceList",
attendanceArrayList);
intent.putExtras(bundle);
startActivity(intent);
}
else if (RegistrationActivity.teacherData != null) {
//
seeAttendanceDetails(RegistrationActivity.teacherData.getEmail(),
batchName,courseName, getDateAndTime);
// Toast.makeText(CoursesActivity.this,"No Record
Found",Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(CoursesActivity.this,
error.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
}) {
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("email", email);
params.put("batch", batchName);
params.put("date", date);
params.put("courseCode",courseCode);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
<br/>
The recycler view activity code
public class ShowAttendanceActivity extends AppCompatActivity implements
ShowAttendanceActivityAdapter.RemoveAttendanceClickListener {
private RecyclerView recyclerView;
private String courseCode,courseName,batchName;
private ArrayList<Attendance> attendanceArrayList = new ArrayList<>();
private TextView
textViewCourseCode,textViewCourseName,textViewBatchName;
private String deleteStudentAttendance =
"https://asuiot.umargulzar.com/Teacher%20API%2
0Files/deleteStudentattendance.php";
int success;
private String TAG_SUCCESS = "success";
private String TAG_MESSAGE = "message";
private String getDateAndTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_attendance);
recyclerView = findViewById(R.id.attendance_details_recyclerView);
textViewCourseCode = findViewById(R.id.SA_textView_course_code);
textViewCourseName = findViewById(R.id.SA_textView_course_name);
textViewBatchName = findViewById(R.id.SA_textView_Batch);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
Calendar calendar = Calendar.getInstance();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMM-yyy hh:mm:ss a");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd");
String dateTime = simpleDateFormat.format(calendar.getTime());
this.getDateAndTime = dateTime;
courseCode = (String) getIntent().getStringExtra("attendanceCourseCode");
courseName = (String) getIntent().getStringExtra("attendanceCourseName");
batchName = (String) getIntent().getStringExtra("attendanceBatchName");
attendanceArrayList = (ArrayList<Attendance>) getIntent().getExtras().getSerializable("attendanceList");
textViewCourseCode.setText(courseCode);
textViewCourseName.setText(courseName);
textViewBatchName.setText(batchName);
recyclerView.setAdapter(new ShowAttendanceActivityAdapter(attendanceArrayList,this));
}
#Override
public void onRemoveAttendanceClick(int position,String email) {
// Toast.makeText(ShowAttendanceActivity.this,"The Email of Student:"+email,Toast.LENGTH_LONG).show();
if(MainActivity.teacherData !=null){
deleteStudentAttendance(email,getDateAndTime,courseCode);
}
}
private void deleteStudentAttendance(final String email, final String getDateAndTime,final String courseCode) {
StringRequest stringRequest = new StringRequest(Request.Method.POST, deleteStudentAttendance, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
success = jsonObject.getInt(TAG_SUCCESS);
if (success == 1) {
Toast.makeText(ShowAttendanceActivity.this, jsonObject.getString(TAG_MESSAGE)+" Plz refresh the page.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ShowAttendanceActivity.this, jsonObject.getString(TAG_MESSAGE), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("Email", email);
params.put("Date",getDateAndTime);
params.put("CourseCode",courseCode);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
the recycler view activity adapter
public class ShowAttendanceActivityAdapter extends RecyclerView.Adapter<ShowAttendanceActivityAdapter.AttendanceView> {
private ArrayList<Attendance> attendanceData;
Bitmap bitmap;
private RemoveAttendanceClickListener removeAttendanceClickListener;
public ShowAttendanceActivityAdapter(ArrayList<Attendance> attendanceData,RemoveAttendanceClickListener removeAttendanceClickListener){
this.attendanceData = attendanceData;
this.removeAttendanceClickListener = removeAttendanceClickListener;
}
#NonNull
#Override
public AttendanceView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.show_attendance_data,parent,false);
return new AttendanceView(view,removeAttendanceClickListener);
}
#Override
public void onBindViewHolder(#NonNull AttendanceView holder, int position) {
Attendance attendance = attendanceData.get(position);
holder.textViewName.setText(attendance.getStudentName());
// holder.textViewEmail.setText(attendance.getStudentEmail());
holder.textViewEmail.setText(attendance.getStudentEmail());
decodeStringToImage(attendance.getStudentPhoto());
holder.imageViewPhoto.setImageBitmap(bitmap);
}
#Override
public int getItemCount() {
return attendanceData.size();
}
public void decodeStringToImage(String photo) {
// Bitmap bitmap = photo.
byte[] bytes = Base64.decode(photo, Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
public class AttendanceView extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView textViewName, textViewEmail;
ImageView imageViewPhoto;
Button buttonRemoveCourse;
RemoveAttendanceClickListener removeAttendanceClickListener;
public AttendanceView(#NonNull View itemView,RemoveAttendanceClickListener removeAttendanceClickListener) {
super(itemView);
textViewName = itemView.findViewById(R.id.textView_name);
textViewEmail = itemView.findViewById(R.id.textView_Email);
imageViewPhoto = itemView.findViewById(R.id.textView_SA_Photo);
this.removeAttendanceClickListener = removeAttendanceClickListener;
buttonRemoveCourse = itemView.findViewById(R.id.btn_remove_attendance);
buttonRemoveCourse.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_remove_attendance:
removeAttendanceClickListener.onRemoveAttendanceClick(getAdapterPosition(),textViewEmail.getText().toString());
break;
}
}
}
public interface RemoveAttendanceClickListener{
void onRemoveAttendanceClick(int position,String email);
}
}
You are probably getting OutOfMemory exception while converting bytes array in to bitmap if the image sizes are huge.
Add try catch in your decodeStringToImage method where you are converting bitmaps and check the log when you load more than 8 images.
I am new to android development and I started working on an expandable RecyclerView. Now My problem is that my child (sub-modules) list is populated dynamically from the selected parent (Module) on the expandable RecyclerView. I tried using a for loop but only the last child list is populated when I open. I was just wondering if there is a way I could implement an item click listener to just return the single selected module.
Here is my adapter:
public class ReportAdapter extends ExpandableRecyclerViewAdapter<ModuleViewHolder, DoiViewHolder> {
Context context;
public ReportAdapter(List<? extends ExpandableGroup> groups, Context context) {
super(groups);
this.context = context;
}
#Override
public ModuleViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module,parent,false);
return new ModuleViewHolder(view);
}
#Override
public DoiViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_doi,parent,false);
return new DoiViewHolder(view);
}
#Override
public void onBindChildViewHolder(DoiViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
ModuleDoi moduleDoi =(ModuleDoi) group.getItems().get(childIndex);
holder.setDoiName(moduleDoi.getName());
}
#Override
public void onBindGroupViewHolder(ModuleViewHolder holder, int flatPosition, ExpandableGroup group) {
holder.setModuleName(group.getTitle());
}
}
Here is my Parent Holder:
public class ModuleViewHolder extends GroupViewHolder implements View.OnClickListener{
TextView moduleName ;
public ModuleViewHolder(View itemView) {
super(itemView);
moduleName = (TextView) itemView.findViewById(R.id.module_name);
}
public void setModuleName(String name){
moduleName.setText(name);
}
}
Here is my Childs holder (Sub Modules)
public class DoiViewHolder extends ChildViewHolder {
TextView doiName;
public DoiViewHolder(View itemView) {
super(itemView);
doiName = (TextView) itemView.findViewById(R.id.module_doi_name);
}
public void setDoiName(String name){
doiName.setText(name);
}
}
Here is where I set the adapter. I am using the
moduleDoiList = fetchModuleMenus(APPID, MODULENAME);
fetch the submodules list from a json file. the app id in this case is a constant and the MODULENAME is obtained from the Modules Array list.
JSONArray jsonArray = jsonObject.getJSONArray("RESPONSE");
moduleDoiList = new ArrayList<>();
appModulesList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject eachModuleObject = jsonArray.getJSONObject(i);
MODULES modules = new MODULES(eachModuleObject.getString("MODULENAME"),
eachModuleObject.getString("MODULEID"));
ModulesList.add(modules);
for(int j = 0; j<ModulesList.size(); j++) {
String moduleTitle = ModulesList.get(i).getModuleName();
String MODULENAME = ModulesList.get(i).getModuleName();
moduleDoiList = fetchModuleMenus(APPID, MODULENAME);
appModulesList.add(new AppModules(moduleTitle, moduleDoiList));
}
}
reportAdapter = new ReportAdapter(appModulesList, POIDocsReportsActivity.this);
reportAdapter.notifyDataSetChanged();
rv.setAdapter(reportAdapter);
This is my fetchModulesMenu method:
public List<ModuleDoi> fetchModuleMenus(final String appId, final String moduleId) {
moduleDoiList = new ArrayList<>();
Thread thread = new Thread() {
Handler handler = new Handler();
ProgressDialog progressDialog;
boolean error;
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
progressDialog = new ProgressDialog(POIDocsReportsActivity.this, R.style.Theme_AppCompat_DayNight_Dialog_Alert);
progressDialog.setMessage("Please wait...");
progressDialog.setCancelable(false);
progressDialog.show();
}
});
String url = AppConfig.SERVER_URL + "load_module_menus.php";
HashMap hashMap = new HashMap();
hashMap.put("APPID", appId);
hashMap.put("MODULEID", moduleId);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url, new JSONObject(hashMap), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
progressDialog.dismiss();
JSONObject jsonObject = new JSONObject(response.toString());
error = jsonObject.getBoolean("ERROR");
if (error){
Toast.makeText(POIDocsReportsActivity.this, "MENUS NOT FOUND ", Toast.LENGTH_LONG).show();
}
else{
JSONArray jsonArray = jsonObject.getJSONArray("RESPONSE");
for (int i = 0; i < jsonArray.length(); i++){
JSONObject eachMenu = jsonArray.getJSONObject(i);
ModuleDoi moduleDoi = new ModuleDoi(eachMenu.getString("POINAME"), eachMenu.getString("POICODE"));
moduleDoiList.add(moduleDoi);
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(POIDocsReportsActivity.this, "CONNECTION ERROR ", Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(POIDocsReportsActivity.this, "NO RESPONSE", Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
}
};
thread.run();
return moduleDoiList;
}
I am using the Thoughtbot Custom Expandable Recycler View
I am making an attendance system where I take the attendance using RadioGroup with two options. When I select some radio button and scroll down some other radio button gets auto-selected. If I change them upper ones also get changed.
Main class
public class TeacherAttendanceActivity extends AppCompatActivity implements AttendanceAdapter.AttendanceAdapterListner {
public static TeacherAttendanceActivity teacherAttendanceActivity;
private static final String TAG = TeacherAttendanceActivity.class.getSimpleName();
List<AttendanceModel> listItems;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private AttendanceAdapter attendanceAdapter;
ProgressDialog progressDialog;
private SQLiteHandler db;
private SessionManager session;
private SearchView searchView;
Button btnSubmit;
JSONObject mainObj = new JSONObject();
// date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDateandTime = sdf.format(new Date());
String class_id,title;
Boolean Error;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teacher_attendance);
//get data from intent
class_id = super.getIntent().getExtras().getString("id"); //class_id
title = super.getIntent().getExtras().getString("title");
getSupportActionBar().setTitle("Class: "+title+", Date: "+currentDateandTime );
// SqLite database handler
db = new SQLiteHandler(getApplicationContext());
// session manager
session = new SessionManager(getApplicationContext());
btnSubmit=findViewById(R.id.buttonAttendanceSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Error=false;
Gson gson=new Gson();
final String newDataArray=gson.toJson(listItems); // dataarray is list aaray
for (int i = 0; i < AttendanceAdapter.listItems.size(); i++){
if(AttendanceAdapter.listItems.get(i).getAttendance()==null){
Toast.makeText(TeacherAttendanceActivity.this, "Check attendance at roll:"+AttendanceAdapter.listItems.get(i).getRoll(), Toast.LENGTH_SHORT).show();
Error =true;
break;
}
}
if (!Error){
request(class_id,currentDateandTime,newDataArray);
}
}
});
listItems = new ArrayList<>();
attendanceAdapter = new AttendanceAdapter(listItems, this, (AttendanceAdapter.AttendanceAdapterListner) this);
recyclerView = (RecyclerView) findViewById(R.id.list_attendance);
recyclerView.setLayoutManager(new LinearLayoutManager(TeacherAttendanceActivity.this));
progressDialog = new ProgressDialog(this);
teacherAttendanceActivity = this;
//refresh_list(class_id);
}
#Override
protected void onStart() {
refresh_list(class_id);
super.onStart();
}
#Override
public void onAttendanceAdapterSelected(AttendanceModel model) {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.refresh, menu);
getMenuInflater().inflate(R.menu.tool_bar, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.action_settings:
Toast.makeText(getApplicationContext(),"Sittings",Toast.LENGTH_LONG).show();
return true;
case R.id.action_logout:
logoutUser();
return true;
case R.id.action_about:
Toast.makeText(getApplicationContext(),"About",Toast.LENGTH_LONG).show();
return true;
case R.id.action_devinfo:
Toast.makeText(getApplicationContext(),"Dev info",Toast.LENGTH_LONG).show();
return true;
case R.id.refresh:
refresh_list(class_id);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
void logoutUser() {
session.setLogin(false);
db.deleteUsers();
// Launching the login activity
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
// refresh list
public void refresh_list(String id) {
// this method refresh list and get the json data
listItems.clear();
// adapter = new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(attendanceAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
progressDialog.setMessage("Loading");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, ApiConfig.URL_TEACHER_ATTENDANCE+id, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
progressDialog.hide();
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("Data"); // finding data
Log.d(TAG, String.valueOf(jsonObject));
int len = jsonArray.length();
for (int i = 0; i < len; i++) {
JSONObject o = jsonArray.getJSONObject(i);
AttendanceModel item = new AttendanceModel(
o.getString("id"),
o.getString("name"),
o.getString("roll"),
o.getString("class_id"),
o.getString("status"),
null
);
listItems.add(item);
//adapter = new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(attendanceAdapter); // setting them in list view
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.hide();
Toast.makeText(TeacherAttendanceActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}) {
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
SQLiteHandler db = new SQLiteHandler(getApplicationContext());
HashMap<String,String> userDetail= db.getUserDetails();
String userToken = userDetail.get("token");
Log.d(TAG, String.valueOf(userToken));
HashMap headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer "+userToken);
return headers;
}
};
stringRequest.setShouldCache(false);
VolleyRequest.getInstance(TeacherAttendanceActivity.this).addToRequestQueue(stringRequest);
}
// take attendance
private void request( final String classId,final String date,final String data ) {
progressDialog.setMessage("Taking attendance");
showDialog();
StringRequest strReq = new StringRequest(Request.Method.POST,
ApiConfig.URL_TEACHER_ATTENDANCE_STORE, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response);
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
String attendance = jObj.getString("Attendance");
Toast.makeText(TeacherAttendanceActivity.this, attendance, Toast.LENGTH_LONG).show();
finish();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("message");
Toast.makeText(TeacherAttendanceActivity.this,
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(TeacherAttendanceActivity.this, "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(TeacherAttendanceActivity.this,
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
SQLiteHandler db = new SQLiteHandler(TeacherAttendanceActivity.this);
HashMap<String,String> userDetail= db.getUserDetails();
String userToken = userDetail.get("token");
Log.d(TAG, String.valueOf(userToken));
HashMap headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer "+userToken);
return headers;
}
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("class_id", classId);
params.put("date", date);
params.put("data", data);
return params;
}
};
strReq.setShouldCache(false);
// Adding request to request queue
VolleyRequest.getInstance(TeacherAttendanceActivity.this).addToRequestQueue(strReq);
}
private void showDialog() {
if (!progressDialog.isShowing())
progressDialog.show();
}
private void hideDialog() {
if (progressDialog.isShowing())
progressDialog.dismiss();
}
}
Model class
'model class for convenient '
public class AttendanceModel {
String id,name,roll,classId,previousAttendance,attendance;
public AttendanceModel(String id, String name,String roll, String classId,String previousAttendance,String attedance ){
this.id = id;
this.name = name;
this.classId =classId;
this.roll=roll;
this.attendance=attedance;
this.previousAttendance=previousAttendance;
}
public String getAttendance() {
return attendance;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getRoll() {
return roll;
}
public String getClassId() {
return classId;
}
public String getPreviousAttendance(){return previousAttendance;}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setRoll(String roll) {
this.roll = roll;
}
public void setClassId(String classId) {
this.classId = classId;
}
public void setPreviousAttendance(String previousAttendance) {
this.previousAttendance = previousAttendance;
}
public void setAttendance(String attendance) {
this.attendance = attendance;
}
}
Adapter class
' adapter class '
public class AttendanceAdapter extends RecyclerView.Adapter<AttendanceAdapter.ViewHolder> implements Filterable
{
// date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDateandTime = sdf.format(new Date());
private static final String TAG = AttendanceAdapter.class.getSimpleName();
public static List<AttendanceModel> listItems;
private List<AttendanceModel> listItemsFiltered;
private Context context;
private ProgressDialog dialog;
private AttendanceAdapter.AttendanceAdapterListner listner;
private ProgressDialog pDialog;
private SQLiteHandler db;
public static JSONObject jo = new JSONObject();
public static JSONArray ja = new JSONArray();
public AttendanceAdapter(List<AttendanceModel> listItems, Context context, AttendanceAdapter.AttendanceAdapterListner listner) {
this.listItems = listItems;
this.listner=listner;
this.context = context;
this.listItemsFiltered =listItems;
// SqLite database handler
db = new SQLiteHandler(context);
// Progress dialog
pDialog = new ProgressDialog(context);
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
listItemsFiltered = listItems;
} else {
List<AttendanceModel> filteredList = new ArrayList<>();
for (AttendanceModel row : listItems) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getName().toUpperCase().contains(charSequence.toString().toUpperCase())||row.getName().toLowerCase().contains(charSequence.toString().toLowerCase())) {
filteredList.add(row);
}
}
listItemsFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = listItemsFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
listItemsFiltered = (ArrayList<AttendanceModel>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView roll;
public TextView previous;
RadioGroup radioAttendance;
RadioButton radioAttendancePresent,radioAttendanceAbsent;
public CardView card_view;
public ViewHolder(View itemView) {
super(itemView);
name= (TextView) itemView.findViewById(R.id.textViewAttendanceStudentName);
roll = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentRoll);
previous = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentPreviousStatus);
radioAttendance = itemView.findViewById(R.id.radioAttendance);
radioAttendancePresent =itemView.findViewById(R.id.radioAttendancePresent);
radioAttendanceAbsent =itemView.findViewById(R.id.radioAttendanceAbsent);
//card_view = (CardView) itemView.findViewById(R.id.class_card_view); // card view for on click method
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View view) {
// send selected contact in callback
listner.onAttendanceAdapterSelected(listItemsFiltered.get(getAdapterPosition())); // selecting cardview and position (model)
}
});
radioAttendance.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
//Toast.makeText(TeacherAttendanceActivity.this, toString(i), Toast.LENGTH_SHORT).show();
// Toast.makeText(context,"clicked at position"+i+" "+id+""+name,Toast.LENGTH_SHORT).show();
if(radioAttendancePresent.isChecked())
{
listItems.get(getAdapterPosition()).setAttendance("present");
}
else {
listItems.get(getAdapterPosition()).setAttendance("absent");
}
}
});
}
}
#Override
public AttendanceAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.attendance_list, parent, false);
return new AttendanceAdapter.ViewHolder(v);
}
#Override
public void onBindViewHolder (final AttendanceAdapter.ViewHolder holder, final int position) {
final AttendanceModel listItem = listItemsFiltered.get(position);
holder.name.setText(listItem.getName());
holder.roll.setText(listItem.getRoll());
holder.previous.setText(listItem.getPreviousAttendance());
}
public interface AttendanceAdapterListner {
void onAttendanceAdapterSelected(AttendanceModel model); // sending cardview to say the dialoge and model for sending context
}
#Override
public int getItemCount() {
return listItemsFiltered.size();
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
Your problem would be solved by making small changes to your Recycler view adapter, please do not disable recyclable property, this makes your recycler view a glorified list view.
I can see you tried using a sparse boolean array to hold the state of the radio buttons, that is good but you do not need that too. The idea behind using a Sparse boolean array is to keep the state of each item in the recycler view so that when they are recycled you still have a reference to what the state of each item is.
In your adapter you already have something that we can use to know the state, that is the attendance property of your model, in that case, you can set the state of your checkboxes by checking if the attendance property is present or absent.
One more thing about your code is that you are using the onCheckChangedListener as a click event handler for your radio button, you should not use this because it responds to all check changed events, even if it is triggered from code and not from user action, so when you bind your view and you set any of your radio buttons as checked or unchecked, it calls this callback.
Here is a modified version of your ViewHolder class that solves this issue by applying the solution above.
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView roll;
public TextView previous;
RadioGroup radioAttendance;
RadioButton radioAttendancePresent, radioAttendanceAbsent;
public CardView card_view;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentName);
roll = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentRoll);
previous = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentPreviousStatus);
radioAttendance = itemView.findViewById(R.id.radioAttendance);
radioAttendancePresent = itemView.findViewById(R.id.radioAttendancePresent);
radioAttendanceAbsent = itemView.findViewById(R.id.radioAttendanceAbsent);
radioAttendancePresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
radioAttendancePresent.setChecked(true);
listItems.get(getAdapterPosition()).setAttendance("present");
}
});
radioAttendanceAbsent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
radioAttendanceAbsent.setChecked(true);
listItems.get(getAdapterPosition()).setAttendance("absent");
}
});
}
void bind(int position) {
// use the sparse boolean array to check
if (listItems.get(position).getAttendance() != null) {
if (listItems.get(position).getAttendance().equals("present")) {
radioAttendancePresent.setChecked(true);
} else if (listItems.get(position).getAttendance().equals("absent")) {
radioAttendanceAbsent.setChecked(true);
}
} else {
radioAttendance.clearCheck();
}
name.setText(listItems.get(position).getName());
roll.setText(listItems.get(position).getRoll());
previous.setText(listItems.get(position).getPreviousAttendance());
}
}
Notice that we have separate click listener for each radio button and set the state in the list of items and just check that state when we are binding, also we have removed the onCheckChangedListener and the sparse boolean array, one last thing is that we made sure that when there is not state set for the attendance property, we just clear the radio buttons so that no one is selected the code is much simpler and works correctly now.
You have to initialize your RadioButton based on model state like below:
#Override
public void onBindViewHolder (final AttendanceAdapter.ViewHolder holder, final int position) {
final AttendanceModel listItem = listItemsFiltered.get(position);
holder.name.setText(listItem.getName());
holder.roll.setText(listItem.getRoll());
holder.previous.setText(listItem.getPreviousAttendance());
final String id =listItem.getId();
final String class_id =listItem.getClassId();
holder.radioAttendance.setOnCheckedChangeListener(null);
if(listItem.getAttendance().equalsIgnoreCase("present")) {
radioAttendancePresent.setChecked(true);
} else {
radioAttendancePresent.setChecked(false);
}
//Add listener here and remove from holder
holder.radioAttendance.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if(holder.radioAttendancePresent.isChecked()) {
listItemsFiltered.get(position).setAttendance("present");
} else {
listItemsFiltered.get(position).setAttendance("absent");
}
notifyDataSetChanged();
}
});
}
I am using a git repo called LikeButton, but the state of my button keeps jumping around in my recyclerview? Here is the repo https://github.com/jd-alexander/LikeButton. Basically when I click on a recyclerview item, it sets a textview to the word true or false based on if the user liked the post or not, and this works. However, the state of my button is doing some weird stuff, it jumps around...
Here is my Adapter, is their anything wrong with it?
public class ViewpagerAdapter extends RecyclerView.Adapter<ViewpagerAdapter.ViewDashboard>{
private LayoutInflater mLayoutInflater;
private ArrayList<QuestionData> data = new ArrayList<>();
public ViewpagerAdapter(Context context) {
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<QuestionData> listBlogs) {
this.data = 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) {
QuestionData questionHolder = data.get(position);
holder.questionText.setText(questionHolder.getMtext());
//This sets the text, to a true or a false String
holder.mStudentVoted.setText(questionHolder.getVoters());
holder.mLikeButton.setTag(holder);
}
#Override
public int getItemCount() {
return data.size();
}
class ViewDashboard extends RecyclerView.ViewHolder {
private TextView questionText;
private LikeButton mLikeButton;
private TextView mStudentVoted;
public ViewDashboard(View itemView) {
super(itemView);
questionText = (TextView)itemView.findViewById(R.id.questionText);
mStudentVoted = (TextView)itemView.findViewById(R.id.studentVoted);
mLikeButton = (LikeButton)itemView.findViewById(R.id.like_button_viewpager);
mLikeButton.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onUpVote();
}
#Override
public void unLiked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onDownVote();
}
});
}
}
}
Voting Class
public class Voting {
private int adapterPosition;
private RecyclerView.Adapter adapter;
private String stringId;
private TextView studentVoted;
//TODO Trim Constructor
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
stringId = questionId.getText().toString();
this.adapter = adapter;
this.studentVoted=studentVoted;
}
public void onUpVote() {
final RequestQueue mRequestQueue = VolleySingleton.getInstance().getRequestQueue();
StringRequest postVoteUp = new StringRequest(Request.Method.PUT, PUT_VOTE_UP, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println("Succesful Upvote The Students Value is " + studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed Upvote");
}
});
mRequestQueue.add(postVoteUp);
}
public void onDownVote() {
final RequestQueue mrequestQueue = VolleySingleton.getInstance().getRequestQueue();
//TODO Delete Token(inserted for student 3 for testing purposes)
StringRequest postVoteDown = new StringRequest(Request.Method.PUT, PUT_VOTE_DOWN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//TODO OnResponse, must setLiked(False)
//Succesful downVote The Students Value is true
//studentVoted.setText("false");
System.out.println("Succesful downVote The Students Value is "+studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed downVote");
}
});
mrequestQueue.add(postVoteDown);
}
public void realTimeUpVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)+1;
textView.setText("" + voteNumber);
}
public void realTimeDownVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)-1;
textView.setText("" + voteNumber);
}
}
Json Request and Parsing Methods
public void JsonRequestMethod() {
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_HOME, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
mListblogs.clear();
mListblogs = new YourTask().execute(response).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mRequestQueue.add(request);
}
private ArrayList<QuestionData> parseJSONResponse(JSONArray response) {
if (!response.equals("")) {
try {
StringBuilder data = new StringBuilder();
for (int x = 0; x < response.length(); x++) {
JSONObject currentQuestions = response.getJSONObject(x);
JSONArray arrSubcategory = currentQuestions.optJSONArray("questions");
for (int y = 0; y < arrSubcategory.length(); y++) {
JSONObject objectSubcategory = arrSubcategory.getJSONObject(y);
String text = objectSubcategory.optString("text");
String studentId = objectSubcategory.optString("studentId");
String votes=objectSubcategory.optString("votes");
/*JSONArray cycles through the array of voters, when a user votes
their ID is added to the array.When they downvote, it is removed
*/
JSONArray voters= objectSubcategory.optJSONArray("voters");
QuestionData questionData = new QuestionData();
questionData.setMstudentId(studentId);
questionData.setMtext(text);
questionData.setVotes(votes);
questionData.setVoters(checkIfVoted(voters));
mQuestionDataArrayList.add(questionData);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mQuestionDataArrayList;
}
private static String checkIfVoted(JSONArray jsonArray ) {
/*pass in a json Array, copy the array into ints, and if
the students Id is contained in the array return the string true
*/
int[] voteIds = new int[jsonArray.length()];
for(int i=0;i<voteIds.length;i++){
voteIds[i] = jsonArray.optInt(i);
}
for(int i=0;i<voteIds.length;i++){
if(voteIds[i]== Integer.parseInt(Login.getUserId())){
//TODO String was only used for Testing purposes, Convert to Boolean later
return "true";
}
}
return "false";
}
you are currently only updating the textview which is why your recycleview changes state when scrolling.
Should change your voting class and pass the question Data rather textview
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
change to
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, QuestionData questionData, TextView studentVoted) {
// make other changes for the data
and then in
public void realTimeUpVoting(QuestionData questionData){
data.votes++ //something like that. idont know your model
// now call back using interface the recyleview data changed method so it updates the count in recycleview automatically.
Edit
passing the question Data in click button
class ViewDashboard extends RecyclerView.ViewHolder {
public int position
public void onBindViewHolder(ViewDashboard holder, int position) {
holder.position = position
}
public void liked(LikeButton likeButton) {
QuestionData questionHolder = data.get(position);
I have three classes, my adapter class, Voting class, and an acitivty where my JSONrequest is as shown below.The problem is as you can see that I call my JSONrequest in my activity which will get a list of views, inside that view I have a mVote textview. In my adapter you can also see I have a likeButton when someone presses that I would like mVotes to change from 0 to 1. I get all my data from a server so I am assuming I would need to make a new request, do I need to make a new adapter to? and JSON parseing method? How do I do this?!??!
public class AdapterQuestion extends RecyclerView.Adapter<AdapterQuestion.ViewQuestion>{
private LayoutInflater mLayoutInflater;
private ArrayList<QuestionData> data =new ArrayList<>();
public AdapterQuestion(Context context){
//get from context
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<QuestionData> data){
this.data =data;
notifyItemRangeChanged(0, this.data.size());
}
#Override
public ViewQuestion onCreateViewHolder(ViewGroup parent, int viewType){
ViewQuestion holder=new ViewQuestion(view);
return holder;
}
#Override
public void onBindViewHolder(ViewQuestion holder, int position) {
holder.answerText.setText(currentObj.getMtext());
holder.answerId.setText(currentObj.getId());
holder.mVotes.setText(currentObj.getVotes());
holder.mLikeButton.setTag(currentObj);
}
#Override
public int getItemCount() {
return data.size();
}
public class ViewQuestion extends RecyclerView.ViewHolder{
private TextView answerText;
private TextView answerId;
private TextView mVotes;
private LikeButton mLikeButton;
public ViewQuestion (View itemView){
super(itemView);
answerText=(TextView)itemView.findViewById(R.id.answerText);
answerId=(TextView)itemView.findViewById(R.id.answerId);
mVotes=(TextView)itemView.findViewById(R.id.VoteTextView);
mLikeButton= (LikeButton)itemView.findViewById(R.id.heart_buttons);
mLikeButton.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Voting vote = new Voting();
vote.onUpVote(answerId());
System.out.print("Adapter Position"+getAdapterPosition());
}
#Override
public void unLiked(LikeButton likeButton) {
Voting onDown=new Voting();
onDown.onDownVote(answerId());
}
});
}
public String getVoteView(){
String voteView=mVotes.getText().toString();
return voteView;
}
public String answerId(){
String converted=answerId.getText().toString();
return converted;
}
public int convertToInt(){
String converted=answerId.getText().toString();
int ConvertedInt=Integer.parseInt(converted);
return ConvertedInt;
}
}
}
Voting
public class Voting {
private VolleySingleton mVolleySingleton;
private RequestQueue mRequestQueue;
private AdapterVoteUpdate mAdapterVotes;
private ArrayList<QuestionData> updateVotes = new ArrayList<>();
public void onUpVote(final String answerId) {
final RequestQueue mrequestQueue = VolleySingleton.getInstance().getRequestQueue();
final String PUT_VOTE_UP = "url" + answerId + "url\n";
StringRequest PostVoteUp = new StringRequest(Request.Method.PUT, PUT_VOTE_UP, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mrequestQueue.add(PostVoteUp);
}
public void onDownVote(final String answerId) {
System.out.println("Voted Down");
final RequestQueue mrequestQueue = VolleySingleton.getInstance().getRequestQueue();
final String PUT_VOTE_DOWN = "url" + answerId + "urul";
StringRequest PostVoteUp = new StringRequest(Request.Method.PUT, PUT_VOTE_DOWN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
System.out.println("************Answer" + error + "error");
}
});
mrequestQueue.add(PostVoteUp);
}
JSON RequestClass
public void JsonRequestMethod(String Id) {
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
final String URL_ANSWER = "url" + Id + "url";
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_ANSWER, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
mListblogs.clear();
mListblogs = parseJSONResponseQuestion(response);
mAdapterQuestion.setBloglist(mListblogs);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
});
mRequestQueue.add(request);
}
private ArrayList<QuestionData> parseJSONResponseQuestion(JSONArray response) {
if (!response.equals("")) {
ArrayList<QuestionData> questionDataArrayList = 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 questionId = currentQuestions.getString("questionId");
String votes = currentQuestions.getString("votes");
System.out.println(votes+" VOTES");
int voteInt=Integer.parseInt(votes);
System.out.println(voteInt);
String Answerid = currentQuestions.getString("id");
String selectedId = currentQuestions.getString("selected");
System.out.println(response.length() + "length");
data.append(text + Answerid + "\n");
System.out.println(data);
QuestionData questionData = new QuestionData();
questionData.setMtext(text);
questionData.setVotes(votes);
questionData.setId(Answerid);
questionData.setSelected(selectedId);
mListblogs.add(questionData);
}
System.out.println(data.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
return mListblogs;
}
"I get all my data from a server so I am assuming I would need to make a new request."
-> Actually you don't need to re-request the data from your server again. You just need to update
private ArrayList<QuestionData> data =new ArrayList<>();
on your AdapterQuestion then call AdapterQuestion.notifyDataSetChanged(); after you get a success response from onUpVote or onDownVote
"Do I need to make a new adapter to? and JSON parseing method? How do I do this?!??!"
-> No need
To change a particular ItemView in your recyclerview use this below code.
notifyItemChanged(index);
If you want to change the particular Textview in onItemclick you have to get the item position.
#Override
public void onBindViewHolder(ViewQuestion holder, int position) {
holder.answerText.setText(currentObj.getMtext());
holder.answerId.setText(currentObj.getId());
holder.mVotes.setText(currentObj.getVotes());
holder.mVotes.setTag(currentObj);
holder.mLikeButton.setTag(holder);
}
In your like button click event change the code like the below
mLikeButton.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Voting vote = new Voting();
vote.onUpVote(answerId());
final ViewQuestion holder=(ViewQuestionholder)likeButton.getTag();
currentObj co=(currentObj)holder.mVotes.getTag();
holder.mVotes.setText("16");
System.out.print("Adapter Position"+getAdapterPosition());
}
#Override
public void unLiked(LikeButton likeButton) {
Voting onDown=new Voting();
onDown.onDownVote(answerId());
final ViewQuestion holder=(ViewQuestionholder)likeButton.getTag();
currentObj co=(currentObj)holder.mVotes.getTag();
holder.mVotes.setText("14");
}
});