I am trying to add flickr images with their titles in a recycler view the problem encountering me is that I want to pass the images and their titles to FlickrPhoto class in the loop (please take a look above to see what I'm saying ) if you notice this line photos.add(new FlickrPhoto(title,uri)); you will see that it inside loop in enqueue function which is at the background task , So I recognize that line doesn't executed .. but when I've tried after enqueue function it works for me but ofcourse for just one image because , I'm outside the loop. I've tried many solutions but all fails
Here is my PhotoListActivity
package com.example.karim.bluecrunch;
/**
* Created by karim on 8/26/16.
*/
public class FlickrPhoto {
String title , image ;
public FlickrPhoto(String title , String image )
{
this.image = image;
this.title = title;
}
}
and here is my PhotosRecyclerViewAdapter
package com.example.karim.bluecrunch;
public class PhotosRecyclerViewAdapter extends RecyclerView.Adapter<PhotosRecyclerViewAdapter.PhotoViewHolder> {
List<FlickrPhoto> photos = Collections.emptyList();
Context context;
LayoutInflater inflater;
public PhotosRecyclerViewAdapter(Context context , List<FlickrPhoto> photos)
{
this.context = context;
this.photos = photos;
inflater = LayoutInflater.from(context);
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = inflater.inflate(R.layout.single_row,parent,false);
return new PhotoViewHolder(row);
}
#Override
public void onBindViewHolder(PhotoViewHolder holder, int position) {
FlickrPhoto photo = photos.get(position);
holder.textView.setText(photo.title);
Uri uri = Uri.parse(photo.image);
Glide.with(context).load(uri).placeholder(R.drawable.image_placeholder).crossFade().into(holder.imageView);
}
#Override
public int getItemCount() {
return photos.size();
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private ImageView imageView;
public PhotoViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.photoTitle);
imageView = (ImageView) itemView.findViewById(R.id.flickrPhoto);
}
}
}
and here is my PhotosListActivity
package com.example.karim.bluecrunch;
public class PhotosListActivity extends AppCompatActivity {
List<FlickrPhoto> photos ;
ArrayList<String> photosTitles;
ArrayList<String> photoURLS;
String title;
String uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photos_list);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.photo_recycler_view);
recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),2));
PhotosRecyclerViewAdapter adapter = new PhotosRecyclerViewAdapter(this,getPhotos());
recyclerView.setAdapter(adapter);
}
public List<FlickrPhoto> getPhotos()
{
photos = new ArrayList<>();
final String API_KEY = "fdac2e9676991ac53b34651adab52518";
final String METHOD = "flickr.photos.search";
final String AUTH_TOKEN = "72157671978046542-6e266595ffed01f8";
final String API_SIG = "58e08d365779a8f2e946a2b5320199e2";
final String FORMAT = "json";
final int CALL_BACK = 1;
HandleRetrofit handleRetrofit = HandleRetrofit.retrofit.create(HandleRetrofit.class);
Call<Photos> call = handleRetrofit.Photos(METHOD,API_KEY,FORMAT,CALL_BACK,AUTH_TOKEN,API_SIG);
call.enqueue(new Callback<Photos>() {
#Override
public void onResponse(Call<Photos> call, Response<Photos> response) {
Log.d("MainActivity", "Status Code = " + response.code());
PhotosRetrofit photosRetrofit = response.body().photos;
for (int i = 0; i < photosRetrofit.getPhoto().size(); i++) {
uri="https://farm"+photosRetrofit.getPhoto().get(i).getFarm()+".staticflickr.com/"+
photosRetrofit.getPhoto().get(i).getServer()+"/"+
photosRetrofit.getPhoto().get(i).getId()+"_" +
photosRetrofit.getPhoto().get(i).getSecret()+".jpg";
title= photosRetrofit.getPhoto().get(i).getTitle();
photos.add(new FlickrPhoto(title,uri));
Log.w(">>>>>>>>>>>","https://farm"+photosRetrofit.getPhoto().get(i).getFarm()+".staticflickr.com/"+
photosRetrofit.getPhoto().get(i).getServer()+"/"+
photosRetrofit.getPhoto().get(i).getId()+"_" +
photosRetrofit.getPhoto().get(i).getSecret()+".jpg");
}
}
#Override
public void onFailure(Call<Photos> call, Throwable t) {
Toast.makeText(PhotosListActivity.this,"Error :"+t.getMessage(),Toast.LENGTH_LONG).show();
Log.w("---___--- Error ",t.getMessage());
}
});
/* Log.w("Hello",uri.toString());
Log.w("Hello",title.toString());*/
photos.add(new FlickrPhoto("karim","https://farm9.staticflickr.com/8450/29141814932_a62977990d.jpg"));
return photos;
}
}
All things works fine , but the main problem at this line in my Activity
photos.add(new FlickrPhoto(title,uri));
I think it can't be done in the background tasks because this line
photos.add(new FlickrPhoto("karim","https://farm9.staticflickr.com/8450/29141814932_a62977990d.jpg"));
works fine after the enqueue function , but I don't know how to do such a trick to solve this problem .
EDIT
Please note that The loop
for (int i = 0; i < photosRetrofit.getPhoto().size(); i++)
{
uri="https://farm"... ;
title= ..;
**photos.add(new FlickrPhoto(title,uri));**
Log.w(">>>>>>>>>>>","https://farm"+photosRetrofit.getPhoto().get(i).getFarm()+".staticflickr.com/"+photosRetrofit.getPhoto().get(i).getServer()+"/"+photosRetrofit.getPhoto().get(i).getId()+"_" +photosRetrofit.getPhoto().get(i).getSecret()+".jpg");
}
doesn't skipped because , if you try to log either title or uri inside the loop it will shown successfully in Logcat . The main problem is that this line of code photos.add(new FlickrPhoto(title,uri)); passes the data "title and uri " to the FlickrPhoto class's constructor and this operation is in the enqueue -> onResponse (Background task) and I don't know why it is not working
It is excepted to load data (Images & Titles ) into recycler view but Actually nothing happens and
I've tried a couple of things
First , before return photos () arrayList at the PhotosListActivity class I've tried to pass a fixed data to the FlickrPhoto class's Constructor And it works and images shown into recycler view
Second , I've tried to add a default constructor and setter , getter for title and image to FlickrPhoto class and initialize it on OnCreate function at PhotosListActivity class then on the enqueue I used my setter and getter and it works and load all data successfully but when I've try to run again everything gone ! :( , and I don't know why
doing setters and getters was like this
FlickrPhoto.java class
package com.example.karim.bluecrunch;
/**
* Created by karim on 8/26/16.
*/
public class FlickrPhoto {
String title , image ;
public FlickrPhoto(){}
public FlickrPhoto(String title , String image )
{
this.image = image;
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
and PostListActivity Class
package com.example.karim.bluecrunch;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.http.Url;
public class PhotosListActivity extends AppCompatActivity {
List<FlickrPhoto> photos ;
ArrayList<String> photosTitles;
ArrayList<String> photoURLS;
FlickrPhoto flickrPhoto ;
String title;
String uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photos_list);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.photo_recycler_view);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
PhotosRecyclerViewAdapter adapter = new PhotosRecyclerViewAdapter(this,getPhotos());
recyclerView.setAdapter(adapter);
flickrPhoto = new FlickrPhoto();
}
public List<FlickrPhoto> getPhotos()
{
photos = new ArrayList<>();
final String API_KEY = "fdac2e9676991ac53b34651adab52518";
final String METHOD = "flickr.photos.search";
final String AUTH_TOKEN = "72157671978046542-6e266595ffed01f8";
final String API_SIG = "58e08d365779a8f2e946a2b5320199e2";
final String FORMAT = "json";
final int CALL_BACK = 1;
HandleRetrofit handleRetrofit = HandleRetrofit.retrofit.create(HandleRetrofit.class);
Call<Photos> call = handleRetrofit.Photos(METHOD,API_KEY,FORMAT,CALL_BACK,AUTH_TOKEN,API_SIG);
call.enqueue(new Callback<Photos>() {
#Override
public void onResponse(Call<Photos> call, Response<Photos> response) {
Log.d("MainActivity", "Status Code = " + response.code());
PhotosRetrofit photosRetrofit = response.body().photos;
//photosRetrofit.getPhoto().size()
for (int i = 0; i < photosRetrofit.getPhoto().size(); i++) {
uri="https://farm"+photosRetrofit.getPhoto().get(i).getFarm()+".staticflickr.com/"+
photosRetrofit.getPhoto().get(i).getServer()+"/"+
photosRetrofit.getPhoto().get(i).getId()+"_" +
photosRetrofit.getPhoto().get(i).getSecret()+".jpg";
title= photosRetrofit.getPhoto().get(i).getTitle();
flickrPhoto.setImage(uri);
flickrPhoto.setTitle(title);
photos.add(new FlickrPhoto(flickrPhoto.getTitle(),flickrPhoto.getImage()));
Log.w("++++++++++++",photosRetrofit.getPhoto().get(i).getTitle());
Log.w(">>>>>>>>>>>","https://farm"+photosRetrofit.getPhoto().get(i).getFarm()+".staticflickr.com/"+
photosRetrofit.getPhoto().get(i).getServer()+"/"+
photosRetrofit.getPhoto().get(i).getId()+"_" +
photosRetrofit.getPhoto().get(i).getSecret()+".jpg");
}
}
#Override
public void onFailure(Call<Photos> call, Throwable t) {
Toast.makeText(PhotosListActivity.this,"Error :"+t.getMessage(),Toast.LENGTH_LONG).show();
Log.w("---___--- Error ",t.getMessage());
}
});
/* Log.w("Hello",uri.toString());
Log.w("Hello",title.toString());*/
photos.add(new FlickrPhoto("karim","https://farm9.staticflickr.com/8450/29141814932_a62977990d.jpg"));
return photos;
}
}
The problem is that RecyclerView does not automatically update after adding elements to the array list with its data. You need to call notifyDataSetChanged() on your adapter to force this update.
Related
I create a RecyclerView with a series of CardViews inside. My end goal is being able to change the text inside of an individual CardView in the activity due to the timing of firebase database calls. My question right now is how does one get the number of items in the RecyclerView?
I know that most will reference me to the Adapter.getItemCount() method. However, at the moment that is only returning zero as the adapter seems to have not been created yet. I believe that this question is more along the lines of the timings of when code runs.
The activity class:
package com.cmsc355.forfit;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.cmsc355.forfit.util.exerciseAdapterClass;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
public class ChallengeView extends AppCompatActivity {
public static Context context;
public static String cCESnapshot;
//Variables
String team;
HashMap<String, String> currChallenges;
ArrayList<String> subAthletes;
ArrayList<String> exerciseList;
ArrayList<String> teamMem;
//System
private Intent intent;
public static String cName;
//XML
private TextView name;
private TextView startDateTV;
private TextView endDateTV;
private TextView description;
private Button bSubscribe;
private Button bDropout;
private ProgressBar difficulty;
//Exercise List
private RecyclerView exerciseRecyclerView;
private RecyclerView.Adapter exerciseAdapter;
private RecyclerView.LayoutManager exerciselayoutManager;
//Database
DatabaseReference databaseReferenceChallenge;
DatabaseReference databaseReferenceAthlete;
#Override
protected void onCreate(Bundle savedInstanceState) {
//Initial setup of activity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_challenge_view);
ChallengeView.context = getApplicationContext();
//variable list
currChallenges = new HashMap<>();
subAthletes = new ArrayList<>();
exerciseList = new ArrayList<>();
teamMem = new ArrayList<>();
//system references
intent = getIntent();
cName = intent.getStringExtra("name");
//cCESnapshot = intent.getStringExtra("snapshot");
//System.out.println(cCESnapshot);
//Authentication references
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
final String uid = user.getUid();
//XML references
name = findViewById(R.id.ChallengeName);
startDateTV = findViewById(R.id.DurationTextStart);
endDateTV = findViewById(R.id.DurationTextEnd);
description = findViewById(R.id.DescriptionText);
difficulty = findViewById(R.id.difficultyBar);
bSubscribe = findViewById(R.id.BSignUp);
bDropout = findViewById(R.id.CV_DropOut);
//Exercise List
exerciseRecyclerView = findViewById(R.id.ExerciseView);
exerciseRecyclerView.setHasFixedSize(true);
exerciselayoutManager = new LinearLayoutManager(this);
exerciseRecyclerView.setLayoutManager(exerciselayoutManager);
exerciseAdapter = new exerciseAdapterClass(exerciseList);
exerciseRecyclerView.setAdapter(exerciseAdapter);
exerciseAdapter.notifyDataSetChanged();
//database references
databaseReferenceChallenge = FirebaseDatabase.getInstance().getReference("Challenges");
databaseReferenceAthlete = FirebaseDatabase.getInstance().getReference("Athlete Users");
//Initial population of views and variables
databaseReferenceChallenge.addValueEventListener(new ValueEventListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot da = dataSnapshot.child(cName);
String dateStart = da.child("StartDate").child("day").getValue() + "/" + da.child("StartDate").child("month").getValue()+ "/" + da.child("StartDate").child("year").getValue();
String dateEnd = da.child("EndDate").child("day").getValue() + "/" + da.child("EndDate").child("month").getValue()+ "/" + da.child("EndDate").child("year").getValue();
long diff = (long)da.child("difficulty").getValue();
int tDifficulty = (int)diff;
name.setText((String)da.child("name").getValue());
startDateTV.setText(dateStart);
endDateTV.setText(dateEnd);
description.setText((String)da.child("description").getValue());
difficulty.setMin(1);
difficulty.setMax(5);
difficulty.setProgress(tDifficulty);
for(DataSnapshot ex : da.child("exercises").getChildren()){
exerciseList.add((String)ex.getValue());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//***************************************************************************************************************************************\\
//This should be grabbing all the challenges that the athlete is currently subscribed to.
databaseReferenceAthlete.addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot dataSnapshot1 = dataSnapshot.child(uid).child("currChallenges");
HashMap<String, String> currChallengesT = (HashMap<String, String>) dataSnapshot1.getValue();
currChallenges.clear();
if(currChallengesT != null) {
currChallenges.putAll(currChallengesT);
if(currChallenges.containsKey(cName)) {
bSubscribe.setVisibility(View.GONE);
bDropout.setVisibility(View.VISIBLE);
}
else{
bSubscribe.setVisibility(View.VISIBLE);
bDropout.setVisibility(View.GONE);
}
}
else{
bSubscribe.setVisibility(View.VISIBLE);
bDropout.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
//***************************************************************************************************************************************\\
//***************************************************************************************************************************************\\
//This should be grabbing all the athletes subscribed to the challenge.
databaseReferenceChallenge.addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot dataSnapshot1 = dataSnapshot.child(cName).child("subscribedAthletes");
ArrayList<String> subAthletesT = (ArrayList<String>) dataSnapshot1.getValue();
if(subAthletesT != null) {
subAthletes.addAll(subAthletesT);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
//***************************************************************************************************************************************\\
databaseReferenceAthlete.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot dataSnapshot1 = dataSnapshot.child(uid).child("currChallenges").child(cName).child("team");
team = (String) dataSnapshot1.getValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
protected void onStart(){
super.onStart();
//This is where I try to call the Recycler View.
System.out.println(exerciseList.size());
for(int i = 0; i < exerciseAdapter.getItemCount(); i ++){
System.out.println("Inside for loop: " + i);
CardView thing = (CardView) exerciselayoutManager.getChildAt(i);
exerciseAdapterClass.exerciseViewHolder holder = (exerciseAdapterClass.exerciseViewHolder) exerciseRecyclerView.getChildViewHolder(thing);
System.out.println("\n\n==============================================================\n" + holder.amount.getText().toString() +
"\n==============================================================");
}
}
public static Context getAppContext() {
return ChallengeView.context;
}
/*
Calls for the transfer to the challenge signup activity
*/
public void Subscribe(View view){
Intent intent = new Intent (this, ChallengeSignUp.class);
intent.putExtra("name", cName);
startActivity(intent);
}
}
The Adapter Class:
package com.cmsc355.forfit.util;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.cmsc355.forfit.ChallengeView;
import com.cmsc355.forfit.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class exerciseAdapterClass extends RecyclerView.Adapter<exerciseAdapterClass.exerciseViewHolder>{
ArrayList<String> exerciseList;
public static class exerciseViewHolder extends RecyclerView.ViewHolder {
public CardView cardView;
public TextView exerciseName;
public TextView amount;
public EditText inputAmount;
public Button bEnter;
DatabaseReference databaseReferenceChallenge;
DatabaseReference databaseReferenceAthlete;
int currDone;
public exerciseViewHolder(View itemView) {
super(itemView);
//Variables
currDone = 0;
//Authentication
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
final String uid = user.getUid();
//Database Reference
databaseReferenceChallenge = FirebaseDatabase.getInstance().getReference("Challenges");
databaseReferenceAthlete = FirebaseDatabase.getInstance().getReference("Athlete Users");
//XML
cardView = itemView.findViewById(R.id.cv_cardView);
exerciseName = itemView.findViewById(R.id.cv_exerciseName);
amount = itemView.findViewById(R.id.cv_amount);
inputAmount = itemView.findViewById(R.id.cv_input);
bEnter = itemView.findViewById(R.id.cv_button);
bEnter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!(inputAmount.getText().toString().trim().length() == 0)){
int input = Integer.parseInt(inputAmount.getText().toString());
final String cName = ChallengeView.cName;
databaseReferenceAthlete.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
try{
DataSnapshot snapshot = dataSnapshot.child(uid).child("currChallenges").child(cName).child(exerciseName.getText().toString());
currDone = (int)((long)snapshot.getValue());
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
currDone += input;
databaseReferenceAthlete.child(uid).child("currChallenges").child(cName).child(exerciseName.getText().toString()).setValue(currDone);
}
else{
Toast.makeText(ChallengeView.getAppContext(), "Nothing in there.", Toast.LENGTH_SHORT).show();
}
}
});
}
}
public exerciseAdapterClass(ArrayList<String> inputList){
exerciseList = inputList;
}
#Override
public int getItemCount() {
return exerciseList.size();
}
#Override
public exerciseViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cv_card, viewGroup, false);
exerciseViewHolder pvh = new exerciseViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(final exerciseViewHolder holder, final int i) {
holder.setIsRecyclable(false);
String s1 = exerciseList.get(i);
//Possible error if the name contains "Amount"
final String name = s1.substring(0, s1.indexOf("Amount")-1); //first section of the string to give the name.
String s2 = s1.substring(s1.indexOf(": ")); //cuts of the front of the string and puts to a new substring.
String a = s2.substring(s2.indexOf(' '), s2.indexOf("\n")); //cuts the part after the : but before the \n
a = a.trim(); //trims the inevitable white space
final String units = a.substring(a.indexOf(' ')); //gets the units off the string
a = a.substring(0, a.indexOf(' ')); //cuts off the units
final int amount = Integer.parseInt(a); //parse to use as a number
String s3 = s2.substring(s2.indexOf("\n")); //cuts to the date and new string
s3 = s3.substring(8); //removes the date tag
String y = s3.substring(0, s3.indexOf('/')); //cuts year into new string
final int year = Integer.parseInt(y); //parse year to use as a number
s3 = s3.substring(s3.indexOf('/') + 1); //cuts year off
String d = s3.substring(0, s3.indexOf('/')); //cuts day into new string
final int day = Integer.parseInt(d); //parse day
s3 = s3.substring(s3.indexOf('/') + 1); //cuts day off
final int month = Integer.parseInt(s3); //parses month
/*DatabaseReference databaseReferenceAthlete = FirebaseDatabase.getInstance().getReference("Athlete Users");
databaseReferenceAthlete.addValueEventListener(new ValueEventListener() {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
final String uid = user.getUid();
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataSnapshot snapshot = dataSnapshot.child(uid).child("currChallenges").child(ChallengeView.cName).child(name);
try{
int val = ((int)((long)snapshot.getValue()));
int printVal = Math.max(0, amount - val);
}
catch(Exception e){}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});*/
holder.amount.setText("0" + units);
holder.exerciseName.setText(name);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
}
As of right now, when I try to call for anything referencing the RecyclerView, it returns either 0 or null. My thought is that the code to instate the RecyclerView has not been run yet.
What you have done is:
In the adapter class, you are trying to retrieve the firebase data.
By the time it returns data the constructor is being called, and where the size of the list exerciseList is zero. And another thing to notice is you have mentioned firebase call (Which operates in the background) in ViewHolder class.
The best way to do this is:
First, you get the data from firebase outside the adapter and then set adapter. Like
In MainActivity do the background job (to retrieve data from Firebase ) and then after successfully retrieve, set adapter like
exerciseAdapterClass adapter = new Adapter (exerciseList);
recyclerView.setAdapter(adapter);
If you want to notify the recycler view if there are some changes occurred in firebase data you can do that as below:
Get the changed list (exerciseList) Or changed item(String) from the firebase using
databaseReferenceAthlete.addValueEventListener
Or
databaseReferenceAthlete.addChildEventListener
and then
adapter.update(exerciseList);
adapter.notifyDatasetChanged;
Or
adapter.update(newString);
adapter.notifyItemChanged(position)
*Note: you have to set up the update method in adapter class
Example:
Adapter to update list
public class NoteListAdapter extends RecyclerView.Adapter<NoteListAdapter.NoteViewHolder> {
private List<String> list;
public NoteListAdapter(List<String> list) {
this.list = list;
}
public void update(List<String> list){
this.list = list;
}
#NonNull
#Override
public NoteViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View noteView = inflater.inflate(R.layout.item_note, parent, false);
return new NoteViewHolder(noteView);
}
#Override
public void onBindViewHolder(#NonNull NoteViewHolder holder, int i) {
String itemString = list.get(i);
holder.textView.setText(itemString);
}
#Override
public int getItemCount() {
return list.size();
}
public class NoteViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public NoteViewHolder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_rv);
}
}
}
in mainActivity:
public class NotesActivity extends AppCompatActivity implements NotesContract.View{
private TextView textView;
private Button add;
private NotesContract.UserActionsListener mActionsListener;
private NoteRepository repository;
private RecyclerView recyclerView;
private NoteListAdapter adapter;
List<String> list = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_view);
add = findViewById(R.id.button);
repository = new NoteRepository();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new NoteListAdapter(list);
recyclerView.setAdapter(adapter);
mActionsListener = new NotePresenter(repository,this);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mActionsListener.loadNotes("hello");
}
});
}
#Override
public void showAddNote(List<String> data) {
String line = "";
for(String s:data){
line = line.concat(s);
}
textView.setText(line);
}
#Override
public void showRecViewNote(List<String> data) {
adapter.update(data);
adapter.notifyDataSetChanged();
}
}
Look at, how the recycler view got set
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new NoteListAdapter(list);
recyclerView.setAdapter(adapter);
and how it is notified
public void showRecViewNote(List<String> data) {
adapter.update(data);
adapter.notifyDataSetChanged();
}
I face a difficulty when working using recyclerview and Gridview. The problem is when my application success load next page (next data), the recyclerview always back to the top.
I want the recyclerview start from last index.
Example : First page load 10 items, after success loan next page, the recycler view start scrolling from item 8.
For resolve that problem, i have tried all the solution on stackoverflow still get nothing.
Here are my code :
package com.putuguna.sitehinduapk.adapters;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.putuguna.sitehinduapk.R;
import com.putuguna.sitehinduapk.activities.DetailBlogPostActivity;
import com.putuguna.sitehinduapk.models.listposts.ItemPostModel;
import com.putuguna.sitehinduapk.utils.GlobalFunction;
import com.putuguna.sitehinduapk.utils.GlobalVariable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class ListPostAdapter extends RecyclerView.Adapter<ListPostAdapter.ViewHolder>{
private List<ItemPostModel> mListPost;
private Context mContext;
public ListPostAdapter(List<ItemPostModel> mListPost, Context mContext) {
this.mListPost = mListPost;
this.mContext = mContext;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.adapter_item_list_post, null);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ItemPostModel post = mListPost.get(position);
List<String> listURL = extractUrls(post.getContentPosting());
Glide.with(mContext)
.load(listURL.get(0))
.into(holder.ivImagePost);
holder.tvTitle.setText(post.getTitle());
holder.llItemPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TO DO OnClick
}
});
List<String> listLabel = post.getListLabel();
String labelPost="";
for(int i=0; i<listLabel.size();i++){
labelPost += "#"+listLabel.get(i) + " ";
}
holder.tvLabel.setText(labelPost);
if ((position >= getItemCount() - 1))
load();
}
public abstract void load();
#Override
public int getItemCount() {
return mListPost.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public ImageView ivImagePost;
public TextView tvTitle;
public LinearLayout llItemPost;
public TextView tvLabel;
public ViewHolder(View itemView) {
super(itemView);
ivImagePost = (ImageView) itemView.findViewById(R.id.iv_image_post);
tvTitle = (TextView) itemView.findViewById(R.id.tv_blog_title);
llItemPost = (LinearLayout) itemView.findViewById(R.id.ll_item_post);
tvLabel = (TextView) itemView.findViewById(R.id.textview_label_adapter);
}
}
public static List<String> extractUrls(String input) {
List<String> result = new ArrayList<String>();
Pattern pattern = Pattern.compile(
"\\b(((ht|f)tp(s?)\\:\\/\\/|~\\/|\\/)|www.)" +
"(\\w+:\\w+#)?(([-\\w]+\\.)+(com|org|net|gov" +
"|mil|biz|info|mobi|name|aero|jobs|museum" +
"|travel|[a-z]{2}))(:[\\d]{1,5})?" +
"(((\\/([-\\w~!$+|.,=]|%[a-f\\d]{2})+)+|\\/)+|\\?|#)?" +
"((\\?([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
"([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)" +
"(&(?:[-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
"([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)*)*" +
"(#([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)?\\b");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
result.add(matcher.group());
}
return result;
}
}
This code of MainActivity.java
private void getListPost(){
mSwipeRefreshLayout.setRefreshing(true);
String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
BloggerApiService apiService = BloggerApiClient.getClient().create(BloggerApiService.class);
Call<ListPostModel> call = apiService.getListPost(GlobalVariable.APP_KEY_V3);
call.enqueue(new Callback<ListPostModel>() {
#Override
public void onResponse(Call<ListPostModel> call, Response<ListPostModel> response) {
ListPostModel listpost = response.body();
initDataView(listpost);
mSwipeRefreshLayout.setRefreshing(false);
}
#Override
public void onFailure(Call<ListPostModel> call, Throwable t) {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
/**
* this method used for post (next page)
*/
private void getNextListPost(){
mSwipeRefreshLayout.setRefreshing(true);
String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
BloggerApiService apiService = BloggerApiClient.getClient().create(BloggerApiService.class);
Call<ListPostModel> call = apiService.getNexPageListPost(GlobalVariable.APP_KEY_V3,nextPageToken);
call.enqueue(new Callback<ListPostModel>() {
#Override
public void onResponse(Call<ListPostModel> call, Response<ListPostModel> response) {
ListPostModel listpost = response.body();
initDataView2(listpost);
mSwipeRefreshLayout.setRefreshing(false);
}
#Override
public void onFailure(Call<ListPostModel> call, Throwable t) {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onRefresh() {
mListPost.clear();
getListPost();
}
private void initDataView(ListPostModel listpost){
GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
mListPost.addAll(listpost.getListItemsPost());
mPostAdapter = new ListPostAdapter(mListPost, this) {
#Override
public void load() {
ItemPostModel item = mListPost.get(mListPost.size()-1);
getNextListPost();
}
};
mRecyclerviewPost.setAdapter(mPostAdapter);
//mPostAdapter.notifyDataSetChanged();
mRecyclerviewPost.setHasFixedSize(true);
mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
}
/**
* this method used for set view (next page)
* #param listpost
*/
private void initDataView2(ListPostModel listpost){
GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
List<ItemPostModel> itemNextPost = listpost.getListItemsPost();
// itemNextPost.addAll(mListPost);
mListPost.addAll(itemNextPost);
mPostAdapter = new ListPostAdapter(mListPost, this) {
#Override
public void load() {
ItemPostModel item = mListPost.get(mListPost.size()-1);
if(nextPageToken==null){
}else{
getNextListPost();
}
}
};
mRecyclerviewPost.setAdapter(mPostAdapter);
mRecyclerviewPost.setHasFixedSize(true);
mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
an
}
Any suggestion will be appreciated.
The problem with the code is, your resetting the complete data again into your adapter and setting it to RecyclerView again, That's why it is re instanced everything in RecyclerView and i.e scrolling to top. Instead of that you can try something like just add /append the updated data into the list ( where you holds the data ) and then just call the adapter.notifyDataSetChanged(); method. automatically it will add the updated data and you no need to set the recycler view again.
Probably for your case you need to change your initDataView2() mehtod like below
private void initDataView2(ListPostModel listpost){
GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
mListPost.addAll(listpost.getListItemsPost());\
mPostAdapter .notifyDataSetChanged();
}
For nextPageToken thing you can move into your main code onCreate() or the initDataView() method where you already have the adapter initialization
like this,
private void initDataView(ListPostModel listpost){
GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
mListPost.addAll(listpost.getListItemsPost());
mPostAdapter = new ListPostAdapter(mListPost, this) {
#Override
public void load() {
ItemPostModel item = mListPost.get(mListPost.size()-1);
if(nextPageToken==null){
}else{
getNextListPost();
}
}
};
mRecyclerviewPost.setAdapter(mPostAdapter);
//mPostAdapter.notifyDataSetChanged();
mRecyclerviewPost.setHasFixedSize(true);
mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
}
I hope it will work :)
I tried data extraction code from many places but everywhere i get how to retrieve data in a simple list. As the structure of my JSON is complex and i can't change it now, so please help me in retrieving data from firebase database. Please help as i am not able to understand Firebase code. Following is my code and JSON database:
CategoryModel.xml
package com.example.firedb;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
/**
* Created by Android on 5/31/2017.
*/
public class CategoryModel {
private ArrayList<CategoryList> categoryList;
public CategoryModel() {
}
public CategoryModel(ArrayList<CategoryList> categoryList) {
this.categoryList = categoryList;
}
public ArrayList<CategoryList> getCategoryList() {
return categoryList;
}
public void setCategoryList(ArrayList<CategoryList> categoryList) {
this.categoryList = categoryList;
}
// CategoryList
public static class CategoryList {
public int Category_id;
public String Category_name;
public ArrayList<String>Emails;
public ArrayList<String>Epabx;
public ArrayList<String>Category_Fax;
public ArrayList<Persons> persons;
public CategoryList() {
}
//constructor of CategoryList
public CategoryList(int category_id, String category_name,
ArrayList<String> emails, ArrayList<String> epabx, ArrayList<String> category_Fax,
ArrayList<Persons> persons) {
Category_id = category_id;
Category_name = category_name;
Emails = emails;
Epabx = epabx;
Category_Fax = category_Fax;
this.persons = persons;
}
// getters and setters of CategoryList
public int getCategory_id() {
return Category_id;
}
public void setCategory_id(int category_id) {
Category_id = category_id;
}
public String getCategory_name() {
return Category_name;
}
public void setCategory_name(String category_name) {
Category_name = category_name;
}
public ArrayList<String> getEmails() {
return Emails;
}
public void setEmails(ArrayList<String> emails) {
Emails = emails;
}
public ArrayList<String> getEpabx() {
return Epabx;
}
public void setEpabx(ArrayList<String> epabx) {
Epabx = epabx;
}
public ArrayList<String> getCategory_Fax() {
return Category_Fax;
}
public void setCategory_Fax(ArrayList<String> category_Fax) {
Category_Fax = category_Fax;
}
public ArrayList<Persons> getPersons() {
return persons;
}
public void setPersons(ArrayList<Persons> persons) {
this.persons = persons;
}
}
//Persons
public static class Persons {
private int Person_ID;
private String Name;
private String Designation;
private ArrayList<String> Office_Phone;
private ArrayList<String> Residence_Phone;
private String VOIP;
private String Address;
private ArrayList<String>Fax;
private String Ext;
private ArrayList<String>Extra_info;
private String Category_name;
public Persons() {
}
// Constructor of Persons
public Persons(int person_ID, String name, String designation, ArrayList<String> office_Phone,
ArrayList<String> residence_Phone, String VOIP, String address, ArrayList<String> fax, String ext,
ArrayList<String>extra_info, String category_name) {
Person_ID = person_ID;
Name = name;
Designation = designation;
Office_Phone = office_Phone;
Residence_Phone = residence_Phone;
this.VOIP = VOIP;
Address = address;
Fax = fax;
Ext = ext;
Extra_info=extra_info;
Category_name=category_name;
}
// Getter and Setters of Persons
public int getPerson_ID() {
return Person_ID;
}
public void setPerson_ID(int person_ID) {
Person_ID = person_ID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getDesignation() {
return Designation;
}
public void setDesignation(String designation) {
Designation = designation;
}
public ArrayList<String> getOffice_Phone() {
return Office_Phone;
}
public void setOffice_Phone(ArrayList<String> office_Phone) {
Office_Phone = office_Phone;
}
public ArrayList<String> getResidence_Phone() {
return Residence_Phone;
}
public void setResidence_Phone(ArrayList<String> residence_Phone) {
Residence_Phone = residence_Phone;
}
public String getVOIP() {
return VOIP;
}
public void setVOIP(String VOIP) {
this.VOIP = VOIP;
}
public String getAddress() {
return Address;
}
public void setAddress(String address) {
Address = address;
}
public ArrayList<String> getFax() {
return Fax;
}
public void setFax(ArrayList<String> fax) {
Fax = fax;
}
public String getExt() {
return Ext;
}
public void setExt(String ext) {
Ext = ext;
}
public ArrayList<String> getExtra_info() {
return Extra_info;
}
public void setExtra_info(ArrayList<String> extra_info) {
Extra_info = extra_info;
}
public String getCategory_name() {
return Category_name;
}
public void setCategory_name(String category_name) {
Category_name = category_name;
}
}
}
CardviewActivity: Earlier i used an asset file but now i want to get data from firebase whose code is ambiguous online
package com.example.firedb;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.LoginFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import static android.R.attr.button;
public class CardViewActivity extends AppCompatActivity {
Toolbar mActionBarToolbar;
private RecyclerView mainRecyclerView;
private RecyclerView.Adapter mainAdapter;
private RecyclerView.LayoutManager mainLayoutManager;
private static String LOG_TAG = "CardViewActivity";
EditText inputSearchMain;
private ArrayList<CategoryModel.CategoryList> categoryLists;
TextView toolbar_title_main;
ImageView back_cardviewActivity;
// DatabaseHandler db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_view);
// db = new DatabaseHandler (CardViewActivity.this);
mActionBarToolbar = (Toolbar) findViewById(R.id.tool_bar);
toolbar_title_main=(TextView)findViewById(R.id.toolbar_title);
// mActionBarToolbar.setTitle("Hry. Govt. Telephone Directory");
// mActionBarToolbar.setLogo(R.drawable.logotoolbar);
// mActionBarToolbar.setTitleMargin(5,2,2,2);
setSupportActionBar(mActionBarToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar_title_main.setText("Hry. Govt. Telephone Directory");
back_cardviewActivity=(ImageView)findViewById(R.id.back);
back_cardviewActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
categoryLists=new ArrayList<CategoryModel.CategoryList>();
categoryLists.addAll(getmcategoryset());
mainRecyclerView=(RecyclerView)findViewById(R.id.recyclerView_Main);
mainRecyclerView.setHasFixedSize(true);
mainLayoutManager=new LinearLayoutManager(this);
mainRecyclerView.setLayoutManager(mainLayoutManager);
// Log.d( "onCreate: ", "List Size: "+categoryLists.size());
mainAdapter=new RecyclerViewAdapterMain(getmcategoryset());
mainRecyclerView.setAdapter(mainAdapter);
inputSearchMain = (EditText) findViewById(R.id.inputSearchMain);
addTextListener();
}
public void addTextListener(){
inputSearchMain.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase();
final ArrayList<CategoryModel.CategoryList> filteredList = new ArrayList<CategoryModel.CategoryList>();
for (int i = 0; i < categoryLists.size(); i++) {
final String text = categoryLists.get(i).getCategory_name().toLowerCase();
if (text.contains(query)) {
filteredList.add(categoryLists.get(i));
}
}
mainRecyclerView.setLayoutManager(new LinearLayoutManager(CardViewActivity.this));
mainAdapter = new RecyclerViewAdapterMain(filteredList);
mainRecyclerView.setAdapter(mainAdapter);
mainAdapter.notifyDataSetChanged(); // data set changed
}
});
}
private ArrayList<CategoryModel.CategoryList> getmcategoryset() {
// JSONObject obj = new JSONObject(readJSONFromAsset());
try {
ArrayList<CategoryModel.CategoryList>categoryList = new ArrayList<CategoryModel.CategoryList>();
JSONObject jsonObject = new JSONObject(readJSONFromAsset());
JSONArray categoryArray = jsonObject.getJSONArray("Category");
Log.d("getmcategoryset", "category count: "+categoryArray.length());
for (int i = 0; i < categoryArray.length(); i++)
{
JSONObject job = categoryArray.getJSONObject(i);
int categoryId = job.getInt("Category_id");
String categoryName = job.getString("Category_name");
//this is for email array
ArrayList<String> emails = new ArrayList<>();
JSONArray emailArray = job.getJSONArray("Emails");
for (int j = 0; j< emailArray.length(); j++){
// JSONObject jobE = emailArray.getString(j);
emails.add(emailArray.getString(j));
}
//This i for Epabx array
ArrayList<String> epabx = new ArrayList<>();
JSONArray epabxArray = job.getJSONArray("Epabx");
for (int j = 0; j < epabxArray.length(); j++){
// JSONObject jobE = epabxArray.getString(j);
epabx.add(epabxArray.getString(j));
}
//This i for Category_Fax array
ArrayList<String> category_Fax = new ArrayList<>();
JSONArray category_FaxJson = job.getJSONArray("Category_Fax");
for (int j = 0; j < category_FaxJson.length(); j++){
// JSONObject jobE = category_FaxJson.getString(j);
category_Fax.add(category_FaxJson.getString(j));
}
//This i for Persons array
ArrayList<CategoryModel.Persons> personsList = new ArrayList<>();
JSONArray personsArray = job.getJSONArray("Persons");
for (int j = 0; j < personsArray.length(); j++){
JSONObject jobIn = personsArray.getJSONObject(j);
int Person_ID = jobIn.getInt("Person_ID");
String Name = jobIn.getString("Name");
String Designation = jobIn.getString("Designation");
//this is for Office_Phone array
ArrayList<String>Office_Phone = new ArrayList<>();
JSONArray office_Phone = jobIn.getJSONArray("Office_Phone");
for (int k=0; k < office_Phone.length(); k++)
{
Office_Phone.add(office_Phone.getString(k));
}
//this is for Residence_Phone array
ArrayList<String>Residence_Phone = new ArrayList<>();
JSONArray residence_Phone = jobIn.getJSONArray("Residence_Phone");
for (int k=0; k < residence_Phone.length(); k++)
{
Residence_Phone.add(residence_Phone.getString(k));
}
String VOIP = jobIn.getString("VOIP");
String Address = jobIn.getString("Address");
//this is for Fax array
ArrayList<String>Fax = new ArrayList<>();
JSONArray fax = jobIn.getJSONArray("Fax");
for (int k=0; k < fax.length(); k++)
{
Fax.add(fax.getString(k));
}
String Ext = jobIn.getString("Ext");
//this is for Extra_info array
ArrayList<String>Extra_info = new ArrayList<>();
JSONArray extra_info = jobIn.getJSONArray("Extra_info");
for (int k=0; k < extra_info.length(); k++)
{
Extra_info.add(extra_info.getString(k));
}
personsList.add(new CategoryModel.Persons(Person_ID, Name, Designation, Office_Phone, Residence_Phone,
VOIP, Address, Fax, Ext,Extra_info,categoryName));
// db.addPerson(new CategoryModel.Persons(Person_ID, Name, Designation, Office_Phone, Residence_Phone,
// VOIP, Address, Fax, Ext,Extra_info));
}
//here your Category[] value store in categoryArrayList
categoryList.add(new CategoryModel.CategoryList(categoryId, categoryName, emails, epabx, category_Fax, personsList));
// db.addCategory(new CategoryModel.CategoryList(categoryId, categoryName, emails, epabx, category_Fax, personsList));
Log.i("categoryList size = ", ""+categoryArray.length());
Log.i("cat_name=",""+categoryName);
}
if (categoryList != null)
{
Log.i("categoryList size = ", ""+categoryArray.length());
}
return categoryList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onResume() {
super.onResume();
// ((RecyclerViewAdapterMain) mainAdapter).setOnItemClickListener(new RecyclerViewAdapterMain()
// .CategoryClickListener() {
// public void onItemClick(int position, View v) {
// Log.i(LOG_TAG, " Clicked on Item " + position);
// }
// });
}
}
RecyclerViewAdapter:
package com.example.firedb;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
public class RecyclerViewAdapterMain extends RecyclerView.Adapter<RecyclerViewAdapterMain.CategoryObjectHolder> {
private static String LOG_TAG = "categoryRecyclrVwAdptr";
private ArrayList<CategoryModel.CategoryList> mcategoryset;
private static CategoryClickListener categoryClickListener;
public static class CategoryObjectHolder extends RecyclerView.ViewHolder {
TextView category_name;
/*TextView category_emails;
TextView category_epabx;
TextView category_fax;*/
public CategoryObjectHolder(View itemView){
super(itemView);
category_name=(TextView)itemView.findViewById(R.id.category_name);
/*category_emails=(TextView)itemView.findViewById(R.id.category_emails);
category_epabx=(TextView)itemView.findViewById(R.id.category_epabx);
category_fax=(TextView)itemView.findViewById(R.id.category_fax);*/
Log.i(LOG_TAG, "Adding Listener");
}
// #Override
// public void onClick(View v) {
// categoryClickListener.onItemClick(getAdapterPosition(), v);
// }
}
// public void setOnItemClickListener(CategoryClickListener categoryClickListener) {
// this.categoryClickListener = categoryClickListener;
// }
public RecyclerViewAdapterMain(ArrayList<CategoryModel.CategoryList> myDataset) {
mcategoryset = myDataset;
}
public CategoryObjectHolder onCreateViewHolder(ViewGroup parent,int viewType){
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_row_main_activity,parent,false);
CategoryObjectHolder categoryObjectHolder=new CategoryObjectHolder(view);
return categoryObjectHolder;
}
#Override
public void onBindViewHolder(CategoryObjectHolder holder, final int position) {
/*final StringBuilder stringBuilder_emails = new StringBuilder();
for (String email : mcategoryset.get(position).getEmails()) {
if (!stringBuilder_emails.toString().isEmpty()) {
stringBuilder_emails.append(", ");
}
stringBuilder_emails.append(email);
}
final StringBuilder stringBuilder_Epabx = new StringBuilder();
for (String epabx : mcategoryset.get(position).getEpabx()) {
if (!stringBuilder_Epabx.toString().isEmpty()) {
stringBuilder_Epabx.append(", ");
}
stringBuilder_Epabx.append(epabx);
}
final StringBuilder stringBuilder_Category_Fax = new StringBuilder();
for (String category_Fax : mcategoryset.get(position).getCategory_Fax()) {
if (!stringBuilder_Category_Fax.toString().isEmpty()) {
stringBuilder_Category_Fax.append(", ");
}
stringBuilder_Category_Fax.append(category_Fax);
}*/
holder.category_name.setText(mcategoryset.get(position).getCategory_name());
/*holder.category_emails.setText(stringBuilder_emails.toString());
holder.category_epabx.setText(stringBuilder_Epabx.toString());
holder.category_fax.setText(stringBuilder_Category_Fax.toString());*/
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent (v.getContext(), PeopleListActivity.class);
i.putParcelableArrayListExtra("Persons",mcategoryset.get(position).getPersons());
i.putStringArrayListExtra("emails",mcategoryset.get(position).getEmails());
//i.putExtras(b);
v.getContext().startActivity(i);
}
});
}
public void addItem(CategoryModel.CategoryList dataObj, int index) {
mcategoryset.add(index, dataObj);
notifyItemInserted(index);
}
public void deleteItem(int index) {
mcategoryset.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return mcategoryset.size();
}
public interface CategoryClickListener {
public void onItemClick(int position, View v);
}
}
The only way to get data from Firebase Database it's using a ValueEventListener.
Firebase work with asynchronous calls, so you can't call the function, get the data and use it. You have to set a ValueEventListener in a specific database reference.
For your actual problem, you have to create an array, set the Firebase Reference, add the ValueEventListener and inside add each occurrence of CategoryList in the array. Finally , still inside of the ValueEventListener, you can create your CategoryModel, with the CategoryList's array as parameter, and update your UI, to see the data in CategoryModel:
CategoryModel categoryModel;
ArrayList<CategoryList> array = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference categoryRef = database.getReference("Category");
categoryRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
CategoryList categoryList = childSnapshot.getValue(CategoryList.class);
array.add(categoryList);
}
categoryModel = new CategoryModel(array);
// Method to show the data in category model,
// usually populating an ListView or something
updateUI()
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
For have this working, your CategoryList class has to implement all the setters of his members so "datasnapshot.getValue()" works.
Another approach can be, create a Constructor in CategoryList that recibe a DataSnapshot in this way:
public CategoryList(DataSnapshot snapshot){
Category_id = snapshot.child("Category_id").getValue(int.class);
Category_name = snapshot.child("Category_name").getValue(String.class);
GenericTypeIndicator<List<String>> stringList = new GenericTypeIndicator<List<String>>() {};
Emails = snapshot.child("Emails").getValue(stringList);
Epabx= snapshot.child("Epabx").getValue(stringList);
Category_Fax= snapshot.child("Category_Fax").getValue(stringList);
GenericTypeIndicator<List<Persons>> personsList = new GenericTypeIndicator<List<Persons>>() {};
persons = snapshot.child("Persons").getValue(personsList);
}
If you create the constructor, you have to replace this line:
CategoryList categoryList = childSnapshot.getValue(CategoryList.class);
with this:
CategoryList categoryList = new CategoryList(childSnapshot);
You can see that I use GenericTypeIndicator to work with collections of data, this is a helper class provide for Firebase to work with Lists, Maps, Sets or another Collection.
Just a recommendation! This is not a good data structure, you should denormalize your data.Then you can observe your data by ChildEventListener or ValueEventListener.
For example:
-Category
--CategoryId
---CategoryList
---Persons
----user1: true
----user2: true, etc.
-Users
--user1Id
---user1details
--user2Id
---user2details, etc.
Here is some useful links about denormalizing your data
Link1,
Link2
I am using restapi to provide data to my app in android and for the database I am using phpmyadmin and do it in localhost, everything goes well, but when I am adding new data in database my recycleview cannot sync with newest data in database so when I swipe or scroll the newest data that I have just added appear as double in my recycleview and it will never end. I am using an emulator to run the apk.
If anyone can help me fix my code I really appreciate it. Here is my customVolleyRequest code:
public class CustomVolleyRequest {
private static CustomVolleyRequest customVolleyRequest;
private static Context context;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private CustomVolleyRequest(Context context) {
this.context = context;
this.requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
#Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized CustomVolleyRequest getInstance(Context context) {
if (customVolleyRequest == null) {
customVolleyRequest = new CustomVolleyRequest(context);
}
return customVolleyRequest;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
Cache cache = new DiskBasedCache(context.getCacheDir(), 10 * 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
}
return requestQueue;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
This is my appconfig class for storing tag:
public class AppConfig {
// Server user login url
public static String URL_LOGIN = "http://192.168.0.13:80/task_manager/v1/login";
// Server user register url
public static String URL_REGISTER = "http://192.168.0.13/task_manager/v1/register";
//URL of my even
public static final String DATA_URL = "http://192.168.0.13/task_manager/v1/even/";
//Tags for my JSON
public static final String TAG_IMAGE_URL = "gambar";
public static final String TAG_JUDUL = "judul";
public static final String TAG_DESKRIPSI = "deskripsi";
public static final String TAG_DUIT = "duit";
public static final String TAG_PERSEN = "persen";
public static final String TAG_SISA_HARI = "sisahari";
}
This is getter and setter:
public class Event {
//Data Variables
private String imageUrl;
private String name;
private String rank;
private int realName;
private int createdBy;
private int firstAppearance;
//private ArrayList<String> powers;
//Getters and Setters
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
//GET AND SET JUDUL
public String getJudul() {
return name;
}
public void setJudul(String name) {
this.name = name;
}
//GET AND SET DESKRIPSI
public String getDeskripsi() {
return rank;
}
public void setDeskripsi(String rank) {
this.rank = rank;
}
//GET AND SET DUIT
public int getDuit() {
return realName;
}
public void setDuit(int realName) {
this.realName = realName;
}
//GET AND SET PERSEN
public int getPersen() {
return createdBy;
}
public void setPersen(int createdBy) {
this.createdBy = createdBy;
}
//GET AND SET SISA HARI
public int getSisaHari() {
return firstAppearance;
}
public void setSisaHari(int firstAppearance) {
this.firstAppearance = firstAppearance;
}
}
And this is my main fragment:
package com.anakacara.anakacara.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.anakacara.anakacara.App.AppConfig;
import com.anakacara.anakacara.App.Event;
import com.anakacara.anakacara.Helper.CardAdapter;
import com.anakacara.anakacara.R;
import com.anakacara.anakacara.activity.DetailEvent;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link EventFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link EventFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class EventFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
//Creating a List of event
private List<Event> listEvent;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private int requestCount = 1;
private int list;
private OnFragmentInteractionListener mListener;
private RequestQueue requestQueue;
private ProgressBar progressBar;
private SwipeRefreshLayout swipeRefreshLayout;
public EventFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment EventFragment.
*/
// TODO: Rename and change types and number of parameters
public static EventFragment newInstance(String param1, String param2) {
EventFragment fragment = new EventFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
private final RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
// code
}
#Override
public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
// code
if (isLastItemDisplaying(recyclerView)) {
//Calling the method getdata again
getData();
}
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View x = inflater.inflate(R.layout.fragment_event,null);;
progressBar = (ProgressBar) x.findViewById(R.id.progressBar1);
recyclerView = (RecyclerView) x.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
listEvent = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity());
swipeRefreshLayout = (SwipeRefreshLayout) x.findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getData();
}
}
);
// listEvent = new ArrayList<>();
// requestQueue = Volley.newRequestQueue(getActivity());
//Calling method to get data
//this method is called twice as if you see
// getData();
// swipeRefreshLayout= (SwipeRefreshLayout) x.findViewById(R.id.swipeRefreshLayout);
// swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
// {
// #Override
// public void onRefresh()
// {
// if (isLastItemDisplaying(recyclerView)) {
////Calling the method getdata again
// getData();
// progressBar.setVisibility(View.GONE);
// }
// }
// });
recyclerView.addOnScrollListener(rVOnScrollListener);
adapter = new CardAdapter(listEvent, getActivity());
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(1000);
itemAnimator.setRemoveDuration(1000);
recyclerView.setItemAnimator(itemAnimator);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Intent intent = new Intent(getActivity(), DetailEvent.class);
intent.putExtra("event_judul", listEvent.get(position).getJudul()); //you can name the keys whatever you like
intent.putExtra("event_deskripsi", listEvent.get(position).getDeskripsi()); //note that all these values have to be primitive (i.e boolean, int, double, String, etc.)
intent.putExtra("event_duit", listEvent.get(position).getDuit());
intent.putExtra("event_persen", listEvent.get(position).getPersen()); //note that all these values have to be primitive (i.e boolean, int, double, String, etc.)
intent.putExtra("event_sisa_hari", listEvent.get(position).getSisaHari());
intent.putExtra("event_image", listEvent.get(position).getImageUrl());
startActivity(intent);
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(getActivity(), "Kepencet Lama " + position, Toast.LENGTH_LONG).show();
}
}));
return x;
}
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
swipeRefreshLayout.setRefreshing(true);
//Displaying Progressbar
progressBar.setVisibility(View.VISIBLE);
// getActivity().getParent().setProgressBarIndeterminateVisibility(true);
//JsonArrayRequest of volley
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(AppConfig.DATA_URL + String.valueOf(requestCount),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
//Calling method parseData to parse the json response
parseData(response);
//Hiding the progressbar
progressBar.setVisibility(View.GONE);
swipeRefreshLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
//If an error occurs that means end of the list has reached
Toast.makeText(getActivity(), "No More Items Available"+list, Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);
}
});
//Returning the request
return jsonArrayRequest;
}
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
requestQueue.add(getDataFromServer(requestCount));
//Incrementing the request counter
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
Event event = new Event();
JSONObject json = null;
try {
json = array.getJSONObject(i);
event.setJudul(json.getString(AppConfig.TAG_JUDUL));
event.setDeskripsi(json.getString(AppConfig.TAG_DESKRIPSI));
event.setDuit(json.getInt(AppConfig.TAG_DUIT));
event.setPersen(json.getInt(AppConfig.TAG_PERSEN));
event.setSisaHari(json.getInt(AppConfig.TAG_SISA_HARI));
event.setImageUrl(json.getString(AppConfig.TAG_IMAGE_URL));
event.setTotal(json.getInt(AppConfig.TAG_TOTAL));
} catch (JSONException e) {
e.printStackTrace();
}
listEvent.add(event);
}
adapter.notifyDataSetChanged();
if( requestCount <= listEvent.get(0).getTotal()) {
requestCount++;
}
//Finally initializing our adapter
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onRefresh() {
if (isLastItemDisplaying(recyclerView)) {
getData();
}
}
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector mGestureDetector;
private ClickListener mClickListener;
public RecyclerTouchListener(final Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.mClickListener = clickListener;
mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
if (child!=null && clickListener!=null){
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
super.onLongPress(e);
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child!=null && mClickListener!=null && mGestureDetector.onTouchEvent(e)){
mClickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
private RecyclerView.OnScrollListener rVOnScrollListener = new RecyclerView.OnScrollListener(){
#Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
// Toast.makeText(getApplicationContext(),
// Config.DATA_URL+String.valueOf(requestCount), Toast.LENGTH_LONG).show();
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isLastItemDisplaying(recyclerView)) {
//Calling the method getdata again
getData();
progressBar.setVisibility(View.GONE);
}
}
};
public static interface ClickListener{
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Here is my adapter:
package com.anakacara.anakacara.Helper;
/**
* Created by Philipus on 05/03/2016.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.anakacara.anakacara.App.CustomVolleyRequest;
import com.anakacara.anakacara.App.Event;
import com.anakacara.anakacara.R;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import java.util.List;
/**
* Created by Belal on 11/9/2015.
*/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
private ImageLoader imageLoader;
private Context context;
//List of eventes
List<Event> eventes;
public CardAdapter(List<Event> eventes, Context context){
super();
//Getting all the eventA
this.eventes = eventes;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.event_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Event event = eventes.get(position);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(event.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
holder.imageView.setImageUrl(event.getImageUrl(), imageLoader);
holder.textViewJudul.setText(event.getJudul());
holder.textViewRank.setText(event.getDeskripsi());
holder.textViewRealName.setText(String.valueOf(event.getDuit()));
holder.textViewCreatedBy.setText(String.valueOf(event.getPersen()));
holder.textViewFirstAppearance.setText(String.valueOf(event.getSisaHari()));
}
#Override
public int getItemCount() {
return eventes.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView imageView;
public TextView textViewJudul;
public TextView textViewRank;
public TextView textViewRealName;
public TextView textViewCreatedBy;
public TextView textViewFirstAppearance;
// public TextView textViewPowers;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewJudul = (TextView) itemView.findViewById(R.id.textViewJudul);
textViewRank= (TextView) itemView.findViewById(R.id.textViewRank);
textViewRealName= (TextView) itemView.findViewById(R.id.textViewRealName);
textViewCreatedBy= (TextView) itemView.findViewById(R.id.textViewCreatedBy);
textViewFirstAppearance= (TextView) itemView.findViewById(R.id.textViewFirstAppearance);
}
}
}
use onRequestFinishedLitener of Volley queue to notifay data set changed.
class RequestListener implements RequestQueue.RequestFinishedListener {
#Override
public void onRequestFinished(Request request) {
adapter.notifyDatasetChanged();
}
}
Then
RequestListener rl = new RequestListener();
volley_queue.addRequestFinishedListener(listener);
if you want to load new data when list comes to the end. you will have to make pages in your API which lying on server. you will have to access page by page. As per the list reaches to end you call parseJson for next page.
you will have call your parseJSON method with new link which contains next data. For this you will have add OnScrollListener of ReyclerView.
class RecyclerViewOnScroll extends RecyclerView.OnScrollListener
{
int temp_page_position;
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if ((list.size()-1 == layoutManager.findLastVisibleItemPosition())) {
// Enters to block when last item of RecyclerView has appeared.
}
}
}
Am looking sample program which could dynamically populating Spinner item from server using Retrofit 1.9 but still I couldn't find any sample can someone share if there is any sample regarding this requirement or else share the method.
How it should be done as am new for android bit struggling to find a solution thanks in advance!
Here is my spinneritem class:
public class MySpinnerItem {
public MySpinnerItem(){
}
public MySpinnerItem(String text, Integer value) {
Text = text;
Value = value;
}
public String getText() {
return Text;
}
public void setText(String text) {
Text = text;
}
public Integer getValue() {
return Value;
}
public void setValue(Integer value) {
Value = value;
}
public String Text;
public Integer Value;
}
Here is my spinner adapter:
package first.service.precision.servicefirst;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
/**
* Created by 4264 on 25-11-2015.
*/
public class MySpinnerAdapter extends ArrayAdapter<MySpinnerItem> {
private Context context;
private List<MySpinnerItem> objects;
public MySpinnerAdapter(Context context, int resource, List<MySpinnerItem> objects) {
super(context, resource, objects);
this.context = context;
this.objects = objects;
}
#Override
public void add(MySpinnerItem object) {
this.objects.add(object);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public MySpinnerItem getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView label = new TextView(context);
label.setText(objects.get(position).getText());
return label;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView label = new TextView(context);
label.setText(objects.get(position).getText());
return label;
}
}
Here is the fragment where i set adapter for spinners:
package first.service.precision.servicefirst;
/**
* Created by 4264 on 23-11-2015.
*/
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import com.squareup.otto.Bus;
import java.util.ArrayList;
import java.util.List;
public class NewRequirements extends Fragment {
Bus bus;
MyListAdapter listAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
List<MySpinnerItem> SbuList = new ArrayList<MySpinnerItem>();
SbuList.add(new MySpinnerItem("Saravanan.R",1));
SbuList.add(new MySpinnerItem("Yogeshwaran",2));
SbuList.add(new MySpinnerItem("Sathesh",3));
SbuList.add(new MySpinnerItem("Barath",4));
SbuList.add(new MySpinnerItem("Deepak",5));
SbuList.add(new MySpinnerItem("Venkat",6));
SbuList.add(new MySpinnerItem("Meena",7));
SbuList.add(new MySpinnerItem("Ram",8));
SbuList.add(new MySpinnerItem("Jegan",9));
View view = inflater.inflate(R.layout.fragment_dialog_claim, container,
false);
final Button btnupdate;
btnupdate = (Button) view.findViewById(R.id.btnAdd);
final Spinner spSbuID = (Spinner) view.findViewById(R.id.spSbuID);
final Spinner spBuID = (Spinner) view.findViewById(R.id.spBuID);
final Spinner spSubBuID = (Spinner) view.findViewById(R.id.spSubBuID);
final Spinner spServiceCategoryID = (Spinner) view.findViewById(R.id.spServiceCategoryID);
final Spinner spServiceSubCategoryID = (Spinner) view.findViewById(R.id.spServiceSubCategoryID);
final EditText txtRequirements=(EditText)view.findViewById(R.id.txtRequirements);
MySpinnerAdapter myadapter = new MySpinnerAdapter(getActivity().getBaseContext(),android.R.layout.simple_spinner_dropdown_item,SbuList);
spSbuID.setAdapter(myadapter);
myadapter = new MySpinnerAdapter(getActivity().getBaseContext(),android.R.layout.simple_spinner_dropdown_item,SbuList);
spBuID.setAdapter(myadapter);
myadapter = new MySpinnerAdapter(getActivity().getBaseContext(),android.R.layout.simple_spinner_dropdown_item,SbuList);
spSubBuID.setAdapter(myadapter);
myadapter = new MySpinnerAdapter(getActivity().getBaseContext(),android.R.layout.simple_spinner_dropdown_item,SbuList);
spServiceCategoryID.setAdapter(myadapter);
myadapter = new MySpinnerAdapter(getActivity().getBaseContext(),android.R.layout.simple_spinner_dropdown_item,SbuList);
spServiceSubCategoryID.setAdapter(myadapter);
try{
Object o;
o = getFragmentManager().findFragmentByTag("add");
Log.v("FIND", o.toString());
}
catch (Exception ex) {
Log.v("FIND", ex.toString());
}
// add.notify();
btnupdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LeadRequirementsView objLeadRequirementsView = new LeadRequirementsView();
MySpinnerItem item;
item = (MySpinnerItem)spSbuID.getSelectedItem();
objLeadRequirementsView.setSbuID(item.getValue());
objLeadRequirementsView.setSbuName(item.getText());
item = (MySpinnerItem)spBuID.getSelectedItem();
objLeadRequirementsView.setBuID(item.getValue());
objLeadRequirementsView.setBuName(item.getText());
item = (MySpinnerItem)spSubBuID.getSelectedItem();
objLeadRequirementsView.setSubBuID(item.getValue());
objLeadRequirementsView.setSubBuName(item.getText());
item = (MySpinnerItem)spServiceCategoryID.getSelectedItem();
objLeadRequirementsView.setServiceCategoryID(item.getValue());
objLeadRequirementsView.setServiceCategoryName(item.getText());
item = (MySpinnerItem)spServiceSubCategoryID.getSelectedItem();
objLeadRequirementsView.setServiceSubCategoryID(item.getValue());
objLeadRequirementsView.setServiceSubCategoryName(item.getText());
objLeadRequirementsView.setDescription(txtRequirements.getText().toString());
Add add;
add = (Add)getFragmentManager().findFragmentByTag("add");
add.updateListView(objLeadRequirementsView);
getActivity().getFragmentManager().popBackStack();
}
});
return view;
}
}
My doubt is i have done it using dummy data but i need to bind the json response from the server to my spinner how come i do this.
Below, is a sample for setting the spinner
Spinner spinner = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adapter;
List<String> data;
data = new ArrayList<>();
for (int i = 0; i < 20; i++)
data.add("Data " + (i + 1));
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
spinner.setAdapter(adapter);
Here data is a dummy data , in your case it will be dummy data.
first create theretrofitapi interface
/**
* reCreated by goodlife on 1/11/2016.
*/
import java.util.List;
import retrofit.Callback;
import retrofit.client.Response;
import retrofit.http.Field;
import retrofit.http.FormUrlEncoded;
import retrofit.http.GET;
import retrofit.http.POST;
/**
* Created by Belal on 11/5/2015.
*/
public interface RetrofitInternetApi {
//#FormUrlEncoded, we have to write this if we want to send post data to the server.
//#POST, because we are using an HTTP Post request we have written this.
// Inside it we have the URL of the script that will be receiving the post request.
// Note that the URL is excluding the root URL. And we have defined the root URL in our MainActivity.
//#Field(“key”) String variable inside key we have to write what we have written inside $_POST[‘key’] in our script.
// And we have to specify it for all the values we are going to send.
//Callback<Response> callback it is also inside the retrofit library. It will receive the output from the server.
//But this is only an interface and the method is abstract.
//We will define the method inside fetchDepartmentName() method that is declared inside MainActivity.java.
#GET("/getDepartmentName.php")
public void getDepartmentName(Callback<List<DepartmentNoRealm>> response);
}
then create the function
private void fetchDepartmentName(){
//Creating a rest adapter
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ROOT_URL)
.build();
//Creating an object of our api interface
RetrofitInternetApi retrofitInternetApi = restAdapter.create(RetrofitInternetApi.class);
//While the app fetched data we are displaying a progress dialog
final ProgressDialog loading = ProgressDialog.show(getActivity(), "Fetching Data", "Please wait...", false, false);
//Defining the method
retrofitInternetApi.getDepartmentName(new Callback<List<DepartmentNoRealm>>() {
#Override
public void success(List<DepartmentNoRealm> list, Response response) {
//Dismissing the loading progressbar
loading.dismiss();
Log.d("JSON LIST",list.toString());
//Storing the data in our list
departmentNoRealmList = list;
//Calling a method to show the list
showListinSpinner(); }
#Override
public void failure(RetrofitError error) {
//you can handle the errors here
}
});
}
then create a class model
package myafya.safaricom.co.ke.myafya.model.realm;
/**
* Created by 001557 on 1/13/2016.
*/
public class DepartmentNoRealm {
public int departmentID;
public String departmentName;
public String departmentURLimage;
public int getDepartmentID() {
return departmentID;
}
public void setDepartmentID(int departmentID) {
this.departmentID = departmentID;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public String getDepartmentURLimage() {
return departmentURLimage;
}
public void setDepartmentURLimage(String departmentURLimage) {
this.departmentURLimage = departmentURLimage;
}
}
now the code showList in Spinner
//Our method to show list
private void showListinSpinner(){
//String array to store all the book names
String[] items = new String[departmentNoRealmList.size()];
//Traversing through the whole list to get all the names
for(int i=0; i<departmentNoRealmList.size(); i++){
//Storing names to string array
items[i] = departmentNoRealmList.get(i).getDepartmentName();
}
//Spinner spinner = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
//setting adapter to spinner
spinnerDepartments.setAdapter(adapter);
//Creating an array adapter for list view
}
Then SHARE IT AND MAKE IT EASY
MY JSON WAS
[
{
"departmentID": "1",
"departmentName": "Enterprise Business Unit (EBU)",
"departmentURLimage": "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcSKOZmGNAA08NbHwRJrloAouWqs6r4x7BGXY4k-ULWiHuPEobHI"
},
{
"departmentID": "2",
"departmentName": "Consumer Business Unit (CBU)",
"departmentURLimage": "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQ0IAFhZ52KiG_0ck5VbBxweZWf_MEA9eRmgHAEr6CG-rUG_a2QEQ"
}
]
try {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<List<People>> call = service.getYear(user_id);
call.enqueue(new Callback<List<People>>()
{
#Override
public void onResponse(Response<List<People>> response, Retrofit retrofit) {
posts = response.body();
String[] s =new String[posts.size()];
for(int i=0;i<posts.size();i++)
{
s[i]= posts.get(i).getYear();
final ArrayAdapter a = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_spinner_item, s);
a.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
Branch.setAdapter(a);
}
}
#Override
public void onFailure(Throwable t) { }
});
} catch (Exception e) {
Log.d("onResponse", "There is an error");
}
}