This question already has answers here:
What is the reason behind "non-static method cannot be referenced from a static context"? [duplicate]
(13 answers)
Closed 3 years ago.
Non-static method cannot be referenced from a non-static context. The problem is coming from my PersonHolder.setPerson(person) with setPerson being underlined. Is this because the setPerson is inside of my onCreate?
I have 3 classes and 4 activity_layouts.
my activity_main class is just for the menu activity_main - just a
menu
Person class
ReadFirebase class attached to my activity_read_firebase which is
meant to pull the data from firebase and put it into my recycler.
WriteToFirebase class used to send data to the firebase.
The last activity is my firebase_item_file that contains the items I require for my recycler in my activity_write_to_firebase.
public class ReadFirebase extends AppCompatActivity {
private FirebaseRecyclerAdapter<Player, PersonHolder> firebaseRecyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read_firebase);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DatabaseReference roofRef = FirebaseDatabase.getInstance().getReference();
Query query = roofRef.child("adult").child("male");
FirebaseRecyclerOptions<Person> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Person>()
.setQuery(query, Person.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Person, PersonHolder>(firebaseRecyclerOptions) {
#Override
protected void onBindViewHolder(#NonNull PersonHolder personHolder, int i, #NonNull Person person) {
PersonHolder.setPerson(person);
}
#NonNull
#Override
public PersonHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.firebase_item_file, parent, false);
return new PersonHolder(view);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
private class PersonHolder extends RecyclerView.ViewHolder {
private TextView name1;
private TextView name2;
private TextView name3;
private TextView age1;
private TextView age2;
private TextView age3;
PersonHolder(View itemView){
super(itemView);
pNameOne = itemView.findViewById(R.id.name1);
pNameTwo = itemView.findViewById(R.id.name2);
pNameThree = itemView.findViewById(R.id.name3);
pAgeOne = itemView.findViewById(R.id.age1);
pAgeTwo = itemView.findViewById(R.id.age2);
pAgeThree = itemView.findViewById(R.id.age3);
}
void setPerson(Person person){
String pName1 = person.getName();
pNameOne.setText(playerName1);
String pName2 = person.getName();
pNameTwo.setText(playerName2);
String pName3= person.getName();
pNameThree.setText(playerName3);
int pAge1= person.getAge();
pAgeOne.setText(Integer.toString(personAge1));
int pAge2 = person.getAge();
pAgeTwo.setText(Integer.toString(personAge2));
int pAge3 = person.getAge();
pAgeThree.setText(Integer.toString(personAge3));
}
}
Non-static method cannot be referenced from a non-static context.
You are trying to access method setPerson using class PersonHolder in onBindViewHolder
You should use instance of PersonHolder which you get in onBindViewHolder as parameter
#Override
protected void onBindViewHolder(#NonNull PersonHolder personHolder, int i, #NonNull Person person) {
personHolder.setPerson(person);
}
Related
I am trying to show all my users. it's not showing even a single of them. I do not know why but my adapter is not working and I also even tried the adapter.startlistening() method. but do not know where to put it. could anyone please just help me?
public class AllUsersActivity extends AppCompatActivity {
private RecyclerView allUsersList;
private DatabaseReference databaseReference;
private FirebaseRecyclerOptions<Users> options;
private FirebaseRecyclerAdapter firebaseRecyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_users);
allUsersList = (RecyclerView)findViewById(R.id.users_list);
allUsersList.setHasFixedSize(true);
allUsersList.setLayoutManager(new LinearLayoutManager(this));
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
}
#Override
protected void onStart() {
super.onStart();
options = new FirebaseRecyclerOptions.Builder<Users>()
.setQuery(databaseReference, Users.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(options) {
#Override
public UsersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_user_layout, parent,false);
return new UsersViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder usersViewHolder, int i, Users users) {
usersViewHolder.setName(users.getName());
}
};
allUsersList.setAdapter(firebaseRecyclerAdapter);
}
}
Assuming that this is the database:
Users
|
|---------UID1
---name
---image
---.....
----------UID2
---name
---image
---......
Make sure that your class Users has the fields exactly like in the database:
class Users{
//these fields must be typed exactly like in the database (watch out for upper case and lower case)
private String name;
private String image;
.........
.........
//also must have a constructor for all fields
//also must have getters and setters for all fields
}
Also in onStart() add this line:
firebaseRecyclerAdapter.startListening();
Directly under this line:
allUsersList.setAdapter(firebaseRecyclerAdapter);
As mentioned in the title, my recyclerview does not work. No idea why, because I do not get any errors or anything in the logcat or while building the app. Is there a way I could debug this or could you point out the mistake that I did?
I've implemented another recyclerview with the adapter, but I used a simple adapter. I tried using the firebaseUI in this case, and it seems that the adapter somehow cannot retrieve the data from the firebase firestore.
https://imgur.com/a/JSLXuou The screenshot of my database structure.
My adapter:
public class ManageAdapter extends FirestoreRecyclerAdapter<Manage, ManageAdapter.ManageHolder> {
public ManageAdapter(#NonNull FirestoreRecyclerOptions<Manage> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ManageHolder holder, int position, #NonNull Manage model) {
holder.textviewName.setText(model.getName());
holder.textviewGrade.setText(model.getGrade());
//holder.textviewAge.setText(String.valueOf(model.getAge()));
}
#NonNull
#Override
public ManageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.manage_item,
parent,false);
return new ManageHolder(v);
}
class ManageHolder extends RecyclerView.ViewHolder{
TextView textviewName;
TextView textviewAge;
TextView textviewGrade;
public ManageHolder(#NonNull View itemView) {
super(itemView);
textviewAge = itemView.findViewById(R.id.manage_item_title_age);
textviewGrade = itemView.findViewById(R.id.manage_item_grade);
textviewName = itemView.findViewById(R.id.manage_item_name);
}
}
}
Main class:
private FirebaseFirestore firebaseFirestore;
private Toolbar mToolbar;
private Button delete_event;
private RecyclerView participants;
private TextView manage_events_title;
private TextView participans_text;
private ManageAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_events);
final String ID = getIntent().getExtras().getString("ID");
firebaseFirestore = FirebaseFirestore.getInstance();
delete_event = (Button) findViewById(R.id.delete_event);
manage_events_title = (TextView) findViewById(R.id.manage_events_title);
participans_text = (TextView) findViewById(R.id.participants_text);
participants = (RecyclerView) findViewById(R.id.recyclerview_manage);
setUpRecyclerView();
}
private void setUpRecyclerView(){
final String ID = getIntent().getExtras().getString("ID");
Query query = firebaseFirestore.collection("Events").document(ID).collection("Users");
FirestoreRecyclerOptions<Manage> options = new FirestoreRecyclerOptions.Builder<Manage>()
.setQuery(query, Manage.class).build();
adapter = new ManageAdapter(options);
participants.setHasFixedSize(true);
participants.setLayoutManager(new LinearLayoutManager(this));
participants.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
I have this code in MainActivity
public class MainActivity extends AppCompatActivity implements MainViewInterface{
RecyclerView rvMovies;
private String TAG = "MainActivity";
MoviesAdapter adapter;
MainPresenter mainPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupMVP();
mainPresenter.getMovies();
rvMovies = (RecyclerView)findViewById(R.id.rvMovies);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
rvMovies.setLayoutManager(manager);
//rvMovies.setHasFixedSize(true);
}
private void setupMVP() {
mainPresenter = new MainPresenter(this);
}
#Override
public void showToast(String s) {
Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
}
#Override
public void displayMovies(MovieResponse moviesResponse) {
if(moviesResponse!=null) {
Log.d(TAG,moviesResponse.getResults().get(1).getTitle());
adapter = new MoviesAdapter(moviesResponse.getResults(), MainActivity.this);
rvMovies.setAdapter(adapter);
adapter.notifyDataSetChanged();
}else{
Log.d(TAG,"Movies response null");
}
}
#Override
public void displayError(String s) {
showToast(s);
}
}
But I get this
E/RecyclerView: No adapter attached; skipping layout
I know other people asked the same question. I tried their solutions but didn't work. What am I missing?
This is my adapter code.
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MoviesHolder> {
List<Result> movieList;
Context context;
public MoviesAdapter(List<Result> movieList, Context context){
this.movieList = movieList;
this.context = context;
}
#Override
public MoviesHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.row_movies,parent,false);
MoviesHolder mh = new MoviesHolder(v);
return mh;
}
#Override
public void onBindViewHolder( MoviesHolder holder, int position) {
holder.tvTitle.setText(movieList.get(position).getTitle());
holder.tvOverview.setText(movieList.get(position).getOverview());
holder.tvReleaseDate.setText(movieList.get(position).getReleaseDate());
Glide.with(context).load("https://image.tmdb.org/t/p/w500/"+movieList.get(position).getPosterPath()).into(holder.ivMovie);
}
#Override
public int getItemCount() {
return movieList.size();
}
public class MoviesHolder extends RecyclerView.ViewHolder {
TextView tvTitle,tvOverview,tvReleaseDate;
ImageView ivMovie;
public MoviesHolder(View itemView) {
super(itemView);
tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
tvOverview = (TextView) itemView.findViewById(R.id.tvOverView);
tvReleaseDate = (TextView) itemView.findViewById(R.id.tvReleaseDate);
ivMovie = (ImageView) itemView.findViewById(R.id.ivMovie);
}
}
Thanks,
Theo.
SOLVED
In my activivity_main.xml I had both height and with equal to 0dp!!! I honestly don't know how and who put those values in!! That's why the recycler view was not visible!!!
I think you should call rvMovies.setAdapter(new MoviesAdapter(new ArrayList<>())) on your RecyclerView during onCreate - there is nothing bad about setting an empty (from items perspective) adapter on RecyclerView, it will simply show an empty list. Then once you have your data ready (downloaded/loaded from any source you are loading from) you will simply call something like adapter.setItems(newItemsList) and adapter.notifyDataSetChanged().
Also one more note: you should not store Context in class member fields as leaks might occur (I am pretty sure your Android Studio must complain about that as well in a form of a Lint Warning check). You actually don't even need that Context instance passing to your adapter as you can simply retrieve a Context instance from parent View in onCreateViewHolder - rewrite it like this:
#Override
public MoviesHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_movies,parent,false);
MoviesHolder mh = new MoviesHolder(v);
return mh;
}
These 2 lines:
setupMVP();
mainPresenter.getMovies();
must be written after:
rvMovies = (RecyclerView)findViewById(R.id.rvMovies);
you need to set adapter after you set the views.
rvMovies = (RecyclerView)findViewById(R.id.rvMovies);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
rvMovies.setLayoutManager(manager);
//rvMovies.setHasFixedSize(true);
//call after setting the view
mainPresenter.getMovies();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupMVP();
rvMovies = (RecyclerView)findViewById(R.id.rvMovies);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
rvMovies.setLayoutManager(manager);
rvMovies.setVisibility(View.VISIBLE);
mainPresenter.getMovies(); <== put this line in last
}
This question already has answers here:
FirebaseRecyclerAdapter unable to populate result [duplicate]
(1 answer)
FirebaseListAdapter not pushing individual items for chat app - Firebase-Ui 3.1
(2 answers)
Closed 5 years ago.
I am following a youtube video in which I was trying to retrieve data using FirebaseUI but I am not able to show any data in the recyclerview.
Here is the code
public class MemeFragment extends Fragment {
RecyclerView recyclerView;
FirebaseDatabase firebaseDatabase;
DatabaseReference myref;
FirebaseRecyclerAdapter<Datafileinfo, ShowDataViewHolder> firebaseRecyclerAdapter;
FirebaseRecyclerOptions<Datafileinfo> options;
public MemeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_meme, container, false);
firebaseDatabase = FirebaseDatabase.getInstance();
myref = FirebaseDatabase.getInstance().getReference("memes");
recyclerView = (RecyclerView) view.findViewById(R.id.recyc);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
options = new FirebaseRecyclerOptions.Builder<Datafileinfo>()
.setQuery(myref, Datafileinfo.class)
.build();
return view;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Datafileinfo, ShowDataViewHolder>
(options) {
#Override
protected void onBindViewHolder(#NonNull ShowDataViewHolder holder, int position, #NonNull Datafileinfo model) {
holder.ImageTitle(model.getTitle());
holder.ImageUrl(model.getImage());
}
#Override
public ShowDataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custo, parent, false);
return new ShowDataViewHolder(view);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class ShowDataViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView textView;
public ShowDataViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
private void ImageTitle(String title) {
textView.setText(title);
}
private void ImageUrl(String url) {
Glide.with(itemView.getContext()).
load(url).
into(imageView);
}
}
}
and datafileinfo is the getter and setter class I have also taken the internet permission.Note I am able to get the single value from firebase but for multiple values, I am facing a problem this is the database.
where I am doing wrong any idea??
Note I have followed and gone through all the tutorials and similar post.
Create a separate Class for your ViewHolder
public class ShowDataViewHolder extends RecyclerView.ViewHolder{
private ImageView imageView;
private TextView textView;
public ShowDataViewHolder (View itemView) {
super(itemView);
imageView = (ImageView)itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
In your MenuFragment add
DatabaseReference mDatabaseMemes= //your reference to memes node
FirebaseRecyclerAdapter<yourModel, ShowDataViewHolder> adapter= new FirebaseRecyclerAdapter<yourModel, ShowDataViewHolder>(yourModel.class, R.layout.yourLayout,
ShowDataViewHolder.class,mDatabaseMemes) {
#Override
protected void populateViewHolder(ShowDataViewHolder viewHolder, yourModel model, int position) {
viewHolder.textView.setText(model.getTitle());
Glide.with(context)
.load(model.getImage())
.fitCenter()
.into(viewHolder.imageView);
}
};
recyclerView.setAdapter(adapter);
}
MAKE SURE your model class has String title and image same as your child names under memes node.
I'm trying to build a simple To Do List app using a RecyclerView with a custom Adapter. I've build a model data class to get and set my todos. My problem is that each time I click the button to add my item, nothing happens. I did call notifyDataSetChanged() method but it still doesn't work.
This is a practice app that I'm building to learn RecyclerViews and custom adapters so I'd appreciate it if someone could explain why it doesn't work and perhaps explain to me how I can fix it.
This is my code where I'm retrieving the user input from the EditText field and placing it in my data:
public class MainActivity extends AppCompatActivity {
private ToDoData toDoData;
private List<ToDoData> toDoList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ToDoAdapter toDoAdapter = new ToDoAdapter(toDoList, this);
toDoData = new ToDoData(this);
final EditText toDoInput = (EditText)findViewById(R.id.add_todo);
Button toDoAdd = (Button)findViewById(R.id.add_item);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
RecyclerView toDoDisplay = (RecyclerView) findViewById(R.id.toDoDisplayRecyclerView);
toDoDisplay.setAdapter(toDoAdapter);
toDoDisplay.setHasFixedSize(true);
toDoDisplay.setLayoutManager(layoutManager);
toDoAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toDoData.setToDo(toDoInput.getText().toString());
toDoAdapter.notifyDataSetChanged();
}
});
}
}
This is my model class with getters and setters. The list-item has only 1 field so its rather small:
public class ToDoData {
private String toDoString;
public ToDoData(String todoString){
this.toDoString = todoString;
}
public ToDoData(Context context){}
public String getToDo() {
return toDoString;
}
public void setToDo(String toDoString) {
this.toDoString = toDoString;
}
}
And this is my custom adapter. I followed through a tutorial while building this but I do however think that my problem stems from the adapter:
public class ToDoAdapter extends RecyclerView.Adapter<ToDoAdapter.ViewHolder> {
private List<ToDoData> toDoList;
private Context context;
public ToDoAdapter(List<ToDoData> todoList, Context context) {
this.toDoList = todoList;
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView todoView;
public ViewHolder(View itemView) {
super(itemView);
todoView = (TextView) itemView.findViewById(R.id.to_do_display);
}
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.to_do_list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ToDoData todo = toDoList.get(position);
holder.todoView.setText(todo.getToDo());
}
#Override
public int getItemCount() {
return (toDoList == null) ? 0 : toDoList.size();
}
}
Add one setter method in your adapter class for setting the collection and then invoke notifyDataSetChanged.
Declare the ToDoAdapter as class member and then invoke the setter function on Button click as follows,
adapter.setTodoList(/* pass collection */);
adapter.notifyDataSetchanged();