hi i am trying use recyclerview. I have two layout one of them mainactivity which has cardview and recyclerview and other one is feeditem xml this one has hold item requirements for show in recyclerview(name,feed,date). But i guess i might have problem onBindViewHolder or VievHolder because i just see mainactivity i cant show anything in recyclerview and the tools inside the feeditem xml actually i can't bind each other.
MainActivity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (R.layout.activity_main);
recyclerView = this.findViewById(R.id.rv_f2);
// recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
databaseReference = database.getReference("allfeed");
FirebaseRecyclerOptions<feedmember> options = new FirebaseRecyclerOptions.Builder<feedmember>().setQuery(databaseReference, feedmember.class).build();
FirebaseRecyclerAdapter<feedmember, VievHolder_feed> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<feedmember, VievHolder_feed>(options) {
#Override
protected void onBindViewHolder(#NonNull VievHolder_feed holder, int position, #NonNull feedmember model)
{ holder.setitem(this , model.getName(), model.getFeed(), model.getTime()); }
#NonNull
#Override
public VievHolder_feed onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item, parent, false);
return new VievHolder_feed(view); }};
firebaseRecyclerAdapter.startListening();
recyclerView.setAdapter(firebaseRecyclerAdapter); }}
Viewholder_feed
public class VievHolder_feed extends RecyclerView.ViewHolder {
TextView time_result,name_result,que_result;
public VievHolder_feed(#NonNull View itemView) { super(itemView); }
public void setitem(FirebaseRecyclerAdapter<feedmember, VievHolder_feed> activity, String name, String time, String feed){
time_result =itemView.findViewById(R.id.time_que_item);
name_result =itemView.findViewById(R.id.name_que_item_tv);
que_result =itemView.findViewById(R.id.que_item_tv);
time_result.setText(time);
name_result.setText( name);
que_result.setText(feed); }}
[]
It seems that your recycler view received the item, but the view holder binds the fields with blank contents.
Did you verify if the mapping inside feedmember class works fine ?
Related
RecyclerView items are not getting created - I'm trying to add a note feature (with MVVM+Room+liveData) to my project.
The same code is fine when used in a new android studio project. implementing it in my existing project is the issue. (both are with androidX and have the same implementations).
Other recyclerViews in my app are working correctly (not with MVVM)
The recycler view adapter is not getting accessed - I used Log flags.
The Code source is from here: https://codinginflow.com/tutorials/android/room-viewmodel-livedata-recyclerview-mvvm/part-6-recyclerview-adapter
Note activity:
public class NoteActivity extends AppCompatActivity {
private NoteViewModel noteViewModel;
ArrayList<Reviews> reviewList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> notes) {
adapter.setNotes(notes);
}
});
}
Note Adapter:
public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
private static final String TAG = "Debug "+NoteAdapter.class.getSimpleName();
private List<Note> notes = new ArrayList<>();
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_item, parent, false);
Log.e (TAG, "in onCreateViewHolder");
return new NoteHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull NoteHolder holder, int position) {
Note currentNote = notes.get(position);
holder.textViewTitle.setText(currentNote.getTitle());
holder.textViewDescription.setText(currentNote.getDescription());
holder.textViewPriority.setText(String.valueOf(currentNote.getPriority()));
Log.e (TAG, "in onBindViewHolder");
}
#Override
public int getItemCount() {
return notes.size();
}
public void setNotes(List<Note> notes) {
this.notes = notes;
notifyDataSetChanged();
}
class NoteHolder extends RecyclerView.ViewHolder {
private TextView textViewTitle;
private TextView textViewDescription;
private TextView textViewPriority;
public NoteHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.text_view_title);
textViewDescription = itemView.findViewById(R.id.text_view_description);
textViewPriority = itemView.findViewById(R.id.text_view_priority);
Log.e (TAG, "in NoteHolder");
}
}
}
the set notes void is the only function getting accessed. (using Log Flags)
The entire code with MVVM classes works in a blank studio project.
What could be the problem??
in Log it get this error:
E/RecyclerView: No adapter attached; skipping layout
The issue is resolved after logging in MVVM components.
I removed the application from my device and installed it again, so the Room database instance was recreated correctly. Apparently, The instance was empty (I don't know why).
btw,
this log error is not part of the issue (you can get it when everything is okay) see previously answered question in the link below
E/RecyclerView: No adapter attached; skipping layout
recyclerview No adapter attached; skipping layout
I am new to android development and encountered an issue while development. First of all look at the design which I want to make.
https://imgur.com/wja71Fl
In the image, the size list is fetched from the server and shown, but here what I want is that suppose another size 11 is given then it should automatically move to the next line. So what I know that recycler view can't be used here. Now how can I achieve this also another point is that how can I make that only one item is selected from the collection of the sizes and selecting another size should de-select the previously selected size. Please provide me some good way to achieve both the targets inefficient way.
To Achive this view . you can use recyclerview with GridLayoutManager . in gridview we have set number of item is one row . try this code to achive this view. in this code i have used a recycler view with a gridview . in this code i have implement only one item select check .
CODE
FirstActivity
public class FirstActivity extends AppCompatActivity{
RecyclerView recycler_view;
GridLayoutManager manager;
static int selectItem=-1;
CustomAdapter customAdapter;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
initView();
}
private void initView(){
ArrayList<String> list=new ArrayList<>();
list.add("8");
list.add("10");
list.add("11");
list.add("12");
list.add("14");
list.add("16");
list.add("18");
recycler_view=findViewById(R.id.recycler_view);
manager=new GridLayoutManager(this, 5);
recycler_view.setLayoutManager(manager);
customAdapter=new CustomAdapter(this, list);
recycler_view.setAdapter(customAdapter);
}
}
CustomAdapter
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyHolder>{
Context context;
ArrayList<String> dataList;
public CustomAdapter(Context context, ArrayList<String> dataList, ){
this.context=context;
this.dataList=dataList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i){
View view=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_custom,viewGroup,false);
MyHolder myHolder=new MyHolder(view);
return myHolder;
}
#Override
public void onBindViewHolder(#NonNull MyHolder myHolder, final int i){
//check select item position
if(selectItem==i){
myHolder.textView.setTextColor(Color.RED);
}else {
myHolder.textView.setTextColor(Color.BLACK);
}
myHolder.textView.setText(dataList.get(i));
myHolder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
selectItem=i;
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount(){
return dataList.size();
}
public class MyHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyHolder(#NonNull View itemView){
super(itemView);
textView=itemView.findViewById(R.id.text_tv);
}
}
}
I Hope It work for you, if any query comment me
Basically we need to get the email from the recyclerview
We tried adding onClickListener on the TextView in the RecyclerView, but when there are more than one entries in the RecyclerView, we cannot get the value.
Is there any way that I can store the values in variables before populating the RecyclerView and passing the values to another Activity?
I tried getting the values from the TextView in the RecyclerView, but I always show the text on the first row
Intent doesn't work on the Adapter class because its not an activity
ArrayList<ModelClass> objModelClassArrayList;
public DatabaseRecyclerAdapter(ArrayList<ModelClass> objModelClassArrayList) {
this.objModelClassArrayList = objModelClassArrayList;
}
#NonNull
#Override
public DatabaseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View singleRow= LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row,parent,false);
return new DatabaseViewHolder(singleRow);
}
#Override
public void onBindViewHolder(#NonNull DatabaseViewHolder holder, int position)
{
ModelClass objModelClass=objModelClassArrayList.get(position);
holder.userNameTV.setText(objModelClass.getName());
holder.userLocation.setText(objModelClass.getAddress());
String e1=objModelClass.getEmail();
holder.userEmail.setText(e1);
}
#Override
public int getItemCount() {
return objModelClassArrayList.size();
}
public static class DatabaseViewHolder extends RecyclerView.ViewHolder
{
TextView userNameTV,userLocation,userEmail;
public DatabaseViewHolder(#NonNull View itemView)
{
super(itemView);
userNameTV=itemView.findViewById(R.id.sr_userNameTV);
userLocation=itemView.findViewById(R.id.sr_location);
userEmail=itemView.findViewById(R.id.sr_email);
}
}
I want to extract the email from a single row and pass it to another page where I can pass it in the DB query to get the results from the database.
first, need to pass context in the constructor of the adapter which can help you to open another activity from the recyclerView adapter. Then Inside BindViewHolder, you can create clickListener like as below,
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String emailText=holder.userEmail.getText().trim();
Intent intent=new Intent(context,activity_name_you _want_ to_open);
intent.setExtra("emailName",emailText);
(name of activity contains RV)context.startActivity(intent)
//Note: here context needs to be typecasted to activity from which we want to open new activity.
}
});
I have implemented RecyclerView show some realm table data. I've created adapter by extending from RealmRecyclerViewAdapter. Even thought I have 3 rows in table (Which I checked by result debugging) nothing showing up in the list. I'm using 'io.realm:android-adapters:2.1.0' adapter and Realm 3.7.2
Here's my code.
Adapter class.
public class UserListAdapter extends RealmRecyclerViewAdapter<User,UserListAdapter.ViewHolder> {
public UserListAdapter(#Nullable OrderedRealmCollection<User> data, boolean autoUpdate) {
super(data, autoUpdate);
setHasStableIds(true);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.user_list_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
User user = getItem(position);
holder.home.setText(user.getUid());
holder.name.setText(user.getName());
holder.home.setText(user.getHouse().getName());
if(user.isStatus()) {
holder.status.setText("Active");
}else{
holder.status.setText("Inactive");
}
}
#Override
public long getItemId(int index) {
return getItem(index).getUid();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#BindView(R.id.column_id)
TextView id;
#BindView(R.id.column_name)
TextView name;
#BindView(R.id.column_house)
TextView home;
#BindView(R.id.status_button)
Button status;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(this);
status.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.status){
//TODO: create interface and add method tho trigger when status click
}else{
//TODO: create interface and add method tho trigger when item click
}
}
}
}
code fragment for setting adapter
try(Realm realm = Realm.getDefaultInstance()){
RealmResults<User> users = realm.where(User.class).findAll();
listAdapter = new UserListAdapter(users,true);
recyclerView.setAdapter(listAdapter);
recyclerView.addItemDecoration(new RecyclerViewDividerVertical(2));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
I could have conver RealmResults<User> in to ArrayList<User> and implement normal RecyclerView Adapter and get it done. But As I've understand RealmRecyclerViewAdapter will result auto update result data in case of data change. But i'm not 100% clear on that too. Can any one explain how that works ? Thanks.
try(Realm realm = Realm.getDefaultInstance()){
RealmResults<User> users = realm.where(User.class).findAll();
listAdapter = new UserListAdapter(users,true);
recyclerView.setAdapter(listAdapter);
recyclerView.addItemDecoration(new RecyclerViewDividerVertical(2));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
} // <--- auto-close!
If you close the Realm instance then the results bound to it become invalidated, and RealmRecyclerViewAdapter checks against isValid() which will return false because you've closed the Realm, so it will be shown with 0 element count.
Refer to proper lifecycle management for UI thread Realm instance (onCreate() open, onDestroy() close) in the documentation.
Looks like your data is invalid and getItemCount() method which is implemented in RealmRecyclerViewAdapter returns 0.
I am developing an android application where i am using a RecyclerView to display a list of items.I am getting the list from server as json.So my problem is within this list i am getting another list as item.That is if my main arraylist contain title and materials, the material is another arraylist.So can you please suggest a solution to display a list within recyclerview.
The code below is my adapter
public class CurriculumAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private ArrayList<Curriculum> mArrayListCurriculum;
public CurriculumAdapter(Context mContext, ArrayList<Curriculum> mArrayListCurriculum) {
this.mContext = mContext;
this.mArrayListCurriculum = mArrayListCurriculum;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_key_features, parent,false);
return new KeyFeatureViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof KeyFeatureViewHolder) {
((KeyFeatureViewHolder) holder).mTextViewFeatureTitle.setText(mArrayListCurriculum.get(position).getTitle());
}
}
#Override
public int getItemCount() {
return mArrayListCurriculum == null ? 0 : mArrayListCurriculum.size();
}
public static class KeyFeatureViewHolder extends RecyclerView.ViewHolder {
public TextView mTextViewFeatureTitle;
public KeyFeatureViewHolder(View itemView) {
super(itemView);
mTextViewFeatureTitle = (TextView) itemView.findViewById(R.id.txtFeature);
}
}
}
The code below is my fragment with dummy arraylist data
public class CourseCurriculumFragment extends Fragment {
private FragmentInterface mFragmentInterface;
private ArrayList<Curriculum> mArrayListCurriculum;
private ArrayList<Material> mArrayListMaterial;
private RecyclerView mRecyclerViewCurriculum;
private LinearLayoutManager mLinearLayoutManager;
private CurriculumAdapter mCurriculumAdapter;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_course_curriculum, container, false);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
mArrayListMaterial = new ArrayList<>();
mArrayListCurriculum = new ArrayList<>();
populateMaterials();
populateKeyFeatures();
mRecyclerViewCurriculum = (RecyclerView) view.findViewById(R.id.recyclerViewCurriculum);
mCurriculumAdapter = new CurriculumAdapter(getActivity(), mArrayListCurriculum);
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerViewCurriculum.setLayoutManager(mLinearLayoutManager);
mRecyclerViewCurriculum.setAdapter(mCurriculumAdapter);
mRecyclerViewCurriculum.setItemAnimator(new DefaultItemAnimator());
}
private void populateMaterials() {
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
}
private void populateKeyFeatures() {
mArrayListCurriculum.add(new Curriculum("UNIT 1",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 2",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 3",mArrayListMaterial));
}
}
A bind method in a holder is a good way to pass data to it.
In your case this bind method should take in a Curriculum and a Material object as parameters.
Inside the onBindViewHolder method of the adapter, instead of reaching into the variables of the holder, you should call this bind method.
In the implementation of the method inside the you KeyFeatureViewHolder class you should use these passed parameters and display them in the appropriate UI elements.
Lastly, to get the Material object data into adapter, add ArrayList<Material> as a constructor parameter just like you did with Curriculum.
Use RecyclerView with header, title as header and materials as items of that header. Look at this example.
You need to design a custom list for yourself. For example take an object like this.
public class ListItem {
public curriculumName = null;
public materialName = null;
}
Now populate this list after you parse the JSON string. Get your first Curriculum and populate the object like this
private ArrayList<ListItem> mListItemArray = new ArrayList<ListItem> ();
for(curriculum : mArrayListCurriculum) {
ListItem mListItemHead = new ListItem();
mListItemHead.curriculumName = curriculum.getName();
// Set the header here
mListItemArray.add(mListItemHead);
for(material : curriculum.getMaterials()){
ListItem mListItem = new ListItem();
mListItem.materialName = material.getName();
// Add materials here
mListItemArray.add(mListItem);
}
}
Now, you've a list with headers and materials. When the materialName in your mListItemArray is null, it identifies that this is a header and vice versa.
Now the trick is to modify your adapter of your RecyclerView so that you can bind proper view to your items in your list.
You can find an indication from this answer on how you can achieve this desired behaviour.
Basically, the idea is to modify your getItemViewType to pass the proper view in your onBindViewHolder. Your getItemViewType might look like this.
#Override
public int getItemViewType(int position) {
if (mListItemArray.get(position).curriculumName != null) {
// This is where we'll add header.
return HEADER_VIEW;
}
return super.getItemViewType(position);
}