I'm creating RecycleView with some items. So I need to get the width and height of the one row of RecycleView
Here I'm creating RecycleView:
RecyclerView rvSmetki = (RecyclerView) findViewById(R.id.rvArtikli);
rvSmetki.setLayoutManager(new GridLayoutManager(this, 3););
rvSmetki.setAdapter(new ArtikliAdapter(this));
// Here I want to get width and height....
And this is my ArtikliAdapter:
public class ArtikliAdapter extends RecyclerView.Adapter<ArtikliAdapter.ViewHolder> {
private static Context context;
private LayoutInflater inflater;
private ArrayList<Artikl> artikliList;
public ArtikliAdapter(Context context) {
this.context = context;
inflater = LayoutInflater.from(context);
artikliList = LogInActivity.getArtiklList();
}
#Override
public ArtikliAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = inflater.inflate(R.layout.artikli_row, parent, false);
return new ArtikliAdapter.ViewHolder(row);
}
#Override
public void onBindViewHolder(ArtikliAdapter.ViewHolder holder, int position) {
Artikl currentArtikl = artikliList.get(position);
holder.tvNaziv.setText(currentArtikl.getNaziv());
holder.tvCena.setText("Цена: " + currentArtikl.getProdaznaCena());
}
#Override
public int getItemCount() {
return artikliList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private RelativeLayout rlArtikl;
private TextView tvNaziv;
private TextView tvCena;
public ViewHolder(View itemView) {
super(itemView);
rlArtikl = (RelativeLayout) itemView.findViewById(R.id.rlArtikl);
tvNaziv = (TextView) itemView.findViewById(R.id.tvNaziv);
tvCena = (TextView) itemView.findViewById(R.id.tvCena);
}
}
}
How can I get width and height of one row?
#Override
public void onBindViewHolder(final MyAdapter.MyViewHolder holder, int position)
{
.....
holder.itemView.post(new Runnable()
{
#Override
public void run()
{
int cellWidth = holder.itemView.getWidth();// this will give you cell width dynamically
int cellHeight = holder.itemView.getHeight();// this will give you cell height dynamically
}
});
.....
}
I hope this will help you!!
Related
I am just practicing the RecyclerView. when I run the App my App crashed I check the log but i cant understand the problem can some help me im waiting for someone responce?
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.name);
}
public TextView getTextView() {
return textView;
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
You need to change the following things in your code:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
//remove this from here.
//private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
//This should be from the layout you have passed in ViewHolder method. in your case from R.layout.contacx. This layout should have two textview with ids:- name and phone respectively.
private final TextView name, phone;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
phone = view.findViewById(R.id.phone);
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
//remvoe this from here.
//view.findViewById(R.id.name);
//view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
//here you should call those view to bind your data like:
viewHolder.name.setText(localDataSet[position].getName());
viewHolder.phone.setText(String.valueOf(localDataSet[position].getPhone()));
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
Use ViewHolder for data bind. More safe
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView name, number;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
number = view.findViewById(R.id.phone);
}
public void bindData(model data) {
name.setText(data.getName());
number.setText(String.valueOf(data.getPhone()));
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
/* No Need
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
*/
return new ViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false););
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
/*
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
*/
viewHolder.bindData(localDataSet[position]);
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
I'm currently building a schedule app where users can input information, and the app will organize the information in a list with each day of the week as the header with each corresponding activity under the day. I'm using a parent child recyclerview to do this (i.e. each day of the week is a part of the parent recyclerview and each activity in the schedule is part of the child recyclerview). Right now I'm trying to add a swipe to delete information in the child recyclerview. Does anyone know how I would go about doing this using the parent child recyclerview configuration, where I have two different adapters for each recyclerview?
Code for Parent RecyclerView:
public class MainRecyclerViewAdapter extends RecyclerView.Adapter<MainRecyclerViewAdapter.ViewHolder> {
ArrayList<DayHeader> weekList;
private Context mContext;
public MainRecyclerViewAdapter(Context mContext, ArrayList<DayHeader> weekList) {
this.mContext = mContext;
this.weekList = weekList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.dayofweekheader,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
DayHeader section = weekList.get(position);
String nameofday = section.getDayName();
ArrayList<medinfo> meditems = section.getmMedItems();
holder.weekdayname.setText(nameofday);
MedicationAdapter childrecyclerAdapter = new MedicationAdapter(mContext,meditems);
holder.childrecyclerview.setAdapter(childrecyclerAdapter);
}
#Override
public int getItemCount() {
return weekList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView weekdayname;
RecyclerView childrecyclerview;
public ViewHolder(#NonNull View itemView) {
super(itemView);
weekdayname = itemView.findViewById(R.id.weekdayheader);
childrecyclerview = itemView.findViewById(R.id.childrecyclerview);
}
}
}
Code for Child RecyclerView:
public class MedicationAdapter extends RecyclerView.Adapter<MedicationAdapter.MedicationViewHolder>{
private ArrayList<medinfo> mMedList;
private Context mContext;
public static class MedicationViewHolder extends RecyclerView.ViewHolder {
public TextView mMedname;
public TextView mTime;
public TextView mNumbPills;
public ImageView popup;
public MedicationViewHolder(#NonNull View itemView) {
super(itemView);
mMedname = itemView.findViewById(R.id.medname);
mTime = itemView.findViewById(R.id.time);
mNumbPills = itemView.findViewById(R.id.numberofpills);
popup = itemView.findViewById(R.id.menumore);
}
}
public MedicationAdapter(Context mContext, ArrayList<medinfo> medList) {
this.mContext = mContext;
this.mMedList = medList;
}
#NonNull
#Override
public MedicationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item,parent,false);
MedicationViewHolder mvh = new MedicationViewHolder(v);
return mvh;
}
#Override
public void onBindViewHolder(#NonNull MedicationViewHolder holder, int position) {
medinfo currentItem = mMedList.get(position);
String medName = "Medication: " + currentItem.getmMedName();
holder.mMedname.setText(medName);
String medTime = "Time: " + currentItem.getmTime();
holder.mTime.setText(medTime);
String numbPills = "# of Pills: " + currentItem.getmNumbPills();
holder.mNumbPills.setText(numbPills);
}
#Override
public int getItemCount() {
return mMedList.size();
}
public void removeItem(int position) {
mMedList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,mMedList.size());
}
}
I also have this SwipeItem class:
public class SwipeItem extends ItemTouchHelper.SimpleCallback {
MedicationAdapter mMedAdapter;
SwipeItem(MedicationAdapter mMedAdapter){
super(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT);
this.mMedAdapter = mMedAdapter;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getBindingAdapterPosition();
this.mMedAdapter.removeItem(position);
}
}
So how can I implement the SwipeItem in my adapter codes to delete each child item?
I'm trying to have my application display a specific layout when the arraylist PinnedSongs is empty.
I've created different viewholders and tried to inflate them depending on the PinnedSongs.size. Meaning, if it's 0, then the onCreateViewHolder should inflate a special layout. If it's different, then inflate another one.
public class RecyclerAdapterHome extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class Viewholder extends RecyclerView.ViewHolder implements View.OnClickListener{
CardView home_cardView;
TextView home_textView;
TextView home_textView_2;
Button home_button;
Button home_button_2;
RelativeLayout parentlayout;
OnNoteListener_2 onNoteListener2;
public Viewholder(#NonNull View itemView, OnNoteListener_2 onNoteListener_2) {
super(itemView);
home_cardView = itemView.findViewById(R.id.cardview_2);
home_textView = itemView.findViewById(R.id.cardview_2_textview);
home_textView_2 = itemView.findViewById(R.id.cardview_2_textview_sub);
home_button = itemView.findViewById(R.id.play_button);
home_button_2 = itemView.findViewById(R.id.push_button);
parentlayout = itemView.findViewById(R.id.home_parentlayout);
home_button.setOnClickListener(this);
this.onNoteListener2 = onNoteListener_2;
}
#Override
public void onClick(View v) {
onNoteListener2.onClick(getAdapterPosition());
}
}
public class Viewholder_2 extends RecyclerView.ViewHolder {
TextView textView_3;
ImageView imageView;
RelativeLayout parentlayout;
public Viewholder_2(#NonNull View itemView) {
super(itemView);
textView_3 = itemView.findViewById(R.id.text_warning);
imageView = itemView.findViewById(R.id.icon);
parentlayout = itemView.findViewById(R.id.home_parentlayout);
}
}
public RecyclerAdapterHome(OnNoteListener_2 mOnNoteListener2, ArrayList<String> pinnedSongs, ArrayList<String> pinnedSongsArtists, Context mContext) {
this.mOnNoteListener2 = mOnNoteListener2;
this.PinnedSongs = pinnedSongs;
this.PinnedSongsArtists = pinnedSongsArtists;
this.mContext = mContext;
}
private ArrayList<String> PinnedSongs = new ArrayList<>();
private ArrayList<String> PinnedSongsArtists = new ArrayList<>();
private Context mContext;
private OnNoteListener_2 mOnNoteListener2;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = null;
if (PinnedSongs.size()==0){
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nothing, parent, false);
return new Viewholder_2(v);
}else{
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.homeviewholder,
parent, false);
return new Viewholder(v,mOnNoteListener2 );
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if (PinnedSongs.size()==0){
Viewholder_2 viewholder_2 = (Viewholder_2) holder;
}else{
Viewholder viewholder = (Viewholder) holder;
viewholder.home_textView.setText(PinnedSongs.get(position));
viewholder.home_textView_2.setText(PinnedSongsArtists.get(position));
}
}
#Override
public int getItemCount() {
return PinnedSongs.size();
}
public interface OnNoteListener_2 {
void onClick(int position);
}
}
So far, the recyclerview shows nothing when the PinnedSongs list is at zero. But it shows something when it's above zero. Any idea on how I can fix it?
(I'm using the androidx libraries if it has anything to do with that).
It doesn't work because the getItemCount method returns 0 and the RecyclerView never tries to instantiate a view.
It means that onBindViewHolder is not called when the size=0.
You have different options to do it. One of these is:
#Override
public int getItemCount() {
return PinnedSongs.size() > 0 ? PinnedSongs.size() : 1;
}
#Override
public int getItemViewType(int position) {
if (PinnedSongs.size() == 0) {
return EMPTY_VIEW;
}
return super.getItemViewType(position);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if (viewType == EMPTY_VIEW) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nothing, parent, false);
EmptyViewHolder emptyViewHolder = new EmptyViewHolder(v);
return emptyViewHolder;
}
//normal case
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.homeviewholder, parent, false);
ViewHolder viewholder = new ViewHolder(v);
return viewholder;
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
public EmptyViewHolder(View itemView) {
super(itemView);
}
}
private static final int EMPTY_VIEW = 1000;
// here is my grid adapter
public class TimeSlotAdapter extends RecyclerView.Adapter {
private LayoutInflater mInflater;
private String strSelectedDate;
List<Boolean> numberList;
private List<String> mData;
private TextView timetv;
List<RelativeLayout> activeTimeSlotsArray=new ArrayList<RelativeLayout>();
// data is passed into the constructor
public TimeSlotAdapter(Context context, List<String> data, String strSelectedDate,TextView timetv,List<Boolean> numberList) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.strSelectedDate = strSelectedDate;
this.timetv=timetv;
this.numberList=numberList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
return new listViewHolder(view);
}
#SuppressLint("ResourceAsColor")
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(position==5||position==11){
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0,0,0,100);
((listViewHolder)holder).timeslot.setLayoutParams(params);
}
((listViewHolder) holder).radioButton.setText(mData.get(position));
((listViewHolder)holder).radioButton.setTextColor(R.color.inactiveslots);
((listViewHolder) holder).timeslot.setBackgroundResource(R.drawable.inactive_slots);
}
#Override
public int getItemCount() {
return mData.size();
}
private class listViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
RadioButton radioButton;
RelativeLayout timeslot;
String strStartTime;
int selectedPosition;
public listViewHolder(View itemView) {
super(itemView);
radioButton = itemView.findViewById(R.id.radioBtton);
timeslot = itemView.findViewById(R.id.mslot1);
timeslot.setOnClickListener(this);
radioButton.setOnClickListener(this);
}
}
When i try to give space the size of the button in position 5 and 11 is changed.Here i am giving the space in gridlayout but the button size i don't want to change it should be in same size.Also the i need space between two rows in a grid
Try this:
LayoutParams params = ((listViewHolder)holder).timeslot.getLayoutParams();
params.setMargins(0,0,0,100);
((listViewHolder)holder).timeslot.setLayoutParams(params);
and check R.layout.grid_item file if radioButton layout_width attribute is wrap_content.
I tried to insert recycleview inside cardview, but it not create it. I think it's problem with adapter, because this type of card created, but not fill recycle view.Now its look like this
There's my recycleview adapter code
public class SubItemsAdapter extends RecyclerView.Adapter<SubItemsAdapter.SubtasksViewHolder>{
private List<Subtask> subtasks;
public SubItemsAdapter(List<Subtask> subtasks){
this.subtasks = subtasks;
}
public class SubtasksViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView;
CheckBox doneCheckBox;
public SubtasksViewHolder(View itemView) {
super(itemView);
titleTextView = (TextView)itemView.findViewById(R.id.subtaskTitle);
doneCheckBox = (CheckBox)itemView.findViewById(R.id.subtaskCheckbox);
}
}
#Override
public SubtasksViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.subtasks_listitem,parent,false);
return new SubtasksViewHolder(v);
}
#Override
public void onBindViewHolder(SubtasksViewHolder holder, int position) {
holder.titleTextView.setText(subtasks.get(position).getText());
holder.doneCheckBox.setChecked(subtasks.get(position).getDone());
}
#Override
public int getItemCount() {
return subtasks.size();
}} `
And my cardview code:
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder> {
ArrayList<TodoItem> todoItems;
int[] dataTypes;
private static final int SIMPLETODOITEM = 0;
private static final int EXTENDTODOITEM = 1;
Context context;
public TasklistAdapter(ArrayList<TodoItem> todoItems, int[] dataTypes, Context context)
{
this.todoItems = todoItems;
this.dataTypes = dataTypes;
this.context = context;
}
public class SimpleViewHolder extends ViewHolder{
TextView titleTextView;
TextView desciptionTextView;
CheckBox doneCheckBox;
public SimpleViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.simpleitem_title_textbox);
desciptionTextView =(TextView)v.findViewById(R.id.simpleitem_description_textbox);
doneCheckBox = (CheckBox)v.findViewById(R.id.simpleitem_checkbox);
}
}
public class ExtendViewHolder extends ViewHolder{
TextView titleTextView;
TextView descTextView;
RecyclerView subtasksListView;
SubItemsAdapter adapter;
RecyclerView.LayoutManager manager;
public ExtendViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.extended_card_title);
descTextView = (TextView)v.findViewById(R.id.extended_card_description);
subtasksListView = (RecyclerView)v.findViewById(R.id.subtasks_listview);
manager = new LinearLayoutManager(v.getContext());
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType)
{
case EXTENDTODOITEM:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.extendedtodoitem_card, parent, false);
return new ExtendViewHolder(v);
default:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.simpletodoitem_card,parent,false);
return new SimpleViewHolder(v);
}
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()){
case EXTENDTODOITEM:
ExtendViewHolder extViewHold = (ExtendViewHolder)holder;
extViewHold.adapter = new SubItemsAdapter(todoItems.get(position).getSubtasks());
extViewHold.titleTextView.setText(todoItems.get(position).getText());
extViewHold.descTextView.setText(todoItems.get(position).getDescription());
extViewHold.subtasksListView.setLayoutManager(extViewHold.manager);
extViewHold.subtasksListView.setAdapter(extViewHold.adapter);
break;
default:
SimpleViewHolder simViewHold = (SimpleViewHolder)holder;
simViewHold.desciptionTextView.setText(todoItems.get(position).getDescription());
simViewHold.titleTextView.setText(todoItems.get(position).getText());
break;
}
}
#Override
public int getItemCount() {
return todoItems.size();
}
#Override
public int getItemViewType(int position) {
return dataTypes[position];
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View v) {
super(v);
}
}
}`
in your TasklistAdapter, static class ViewHolder extending RecyclerView.ViewHolder seems useless! and you are trying to inflate and bind data with two heterogeneous layouts with their own viewholder sub-classes! My solution would be to change this :
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder>
to
public class TasklistAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>