I want to make a RecyclerView where a new view is created by a value in an object.
I have a list of devices which has a variable 'dimmable'.
When it is dimmable, the ViewHolder has to create a new SeekBar. When it is not dimmable, the ViewHolder has to create a new Switch.
I know I cannot use the position in the onCreateViewHolder, but is there another way to get a device based on the position where I can check if it is dimmable or not and than create a new SeekBar or Switch?
private List<Device> mDevices;
private DeviceClickListener mListener;
public DeviceRecyclerViewAdapter(List<Device> mDevices, DeviceClickListener mListener) {
Logger.debug("DeviceRecyclerViewAdapter called.");
this.mDevices = mDevices;
this.mListener = mListener;
}
@NonNull
@Override
public DeviceRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Logger.debug("onCreateViewHolder called.");
Context context = parent.getContext();
LayoutInflater inflator = LayoutInflater.from(context);
// create a new view
View deviceListItem = inflator.inflate(R.layout.device, parent, false);
DeviceRecyclerViewAdapter.ViewHolder viewHolder = new ViewHolder(deviceListItem);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull DeviceRecyclerViewAdapter.ViewHolder holder, int position) {
Logger.debug("onBindViewHolder called.");
Device device = mDevices.get(position);
//Here I will set the names of the devices, checking switches or set the progress on the seekbar.
holder.title.setText(device.getName());
}
@Override
public int getItemCount() {
Logger.debug("getItemCount called - " mDevices.size());
return mDevices.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// ViewHolder is the view of a device_list_item
// one device_list_item contains multiple views
// Provide a reference to each view in the device_list_item
public TextView title;
public ViewHolder(View listItemView) {
super(listItemView);
Logger.debug("ViewHolder called.");
title = listItemView.findViewById(R.id.device_item_title);
Device device = mDevices.get(###); //Tried to get the position
LinearLayout linearLayout = listItemView.findViewById(R.id.ll_devicebar);
--> if(device.isDimmable()){
--> SeekBar dimbar = new SeekBar(listItemView.getContext());
linearLayout.addView(dimbar);
} else {
--> Switch onOffSwitch = new Switch(listItemView.getContext());
linearLayout.addView(onOffSwitch);
}
}
@Override
public void onClick(View view) {
Logger.debug("onClick called.");
int position = getAdapterPosition();
mListener.onItemClick(position);
}
}
public interface DeviceClickListener {
void onItemClick(int position);
}
}
Thanks in advance.
CodePudding user response:
You can create two different views/viewholders for your recyclerview by overriding getItemViewType(int position).
In this method you would get the data for the position that is given and see check if you should use the view with the switch or the view with the seekbar
@Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
if(myData.get(position).dimmable){
return 1
}else{
return 0
}
}
then in your onCreateViewHolder you check the given viewType and inflate the correct view holder based on it
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 0) {
return new ViewHolder1(LayoutInflater.from(context).inflate(R.layout.myLayoutWithSwitch, parent, false));
}else{
return new ViewHolder2(LayoutInflater.from(context).inflate(R.layout.myLayoutWithSeekbar, parent, false));
}
}
Then in onBindViewHolder cast the view holder to the appropriate type
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (myData.get(position).dimmable) {
((ViewHolder1) holder).dimbar //do something with the dimmer;
} else {
((ViewHolder2) holder).onOffSwitch //do something with the switch;
}
}
CodePudding user response:
Here is a complete sample to show a RecyclerView with two types, the view type decided by the object using enum class to check the View type
private List<Device> mDevices;
private DeviceClickListener mListener;
enum ViewType {
View_SEEK_BAR,
VIEW_SWITCH
}
public DeviceRecyclerViewAdapter(List<Device> mDevices, DeviceClickListener mListener) {
Logger.debug("DeviceRecyclerViewAdapter called.");
this.mDevices = mDevices;
this.mListener = mListener;
}
@Override
public int getItemViewType(int position) {
if (mDevices.get(position).isDumbble()) {
return ViewType.VIEW_SWITCH.ordinal();
} else {
return ViewType.View_SEEK_BAR.ordinal();
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ViewType.VIEW_SWITCH.ordinal()) {
return new ItemWithSwitchViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item_with_switch, parent, false));
} else {
return new ItemWithSeekbar(LayoutInflater.from(context).inflate(R.layout.list_item_with_seekbar, parent, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ItemWithSwitchViewHolder) {
((ItemWithSwitchViewHolder) holder).bind(mDevices.get(position));
} else {
((ItemWithSeekbarViewHolder) holder).bind(mDevices.get(position));
}
}
@Override
public int getItemCount() {
return mDevices.size();
}
class ItemWithSwitchViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
Switch aSwitch;
public ItemWithSwitchViewHolder(@NonNull View itemView) {
super(itemView);
// Update the views
aSwitch = itemView.findViewById(R.id.switch_id);
}
void bind(Device device) {
// Do something with the switch and u have item here
}
@Override
public void onClick(View view) { }
}
class ItemWithSeekbarViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
SeekBar seekBar;
public ItemWithSeekbarViewHolder(@NonNull View itemView) {
super(itemView);
// Update the views
seekBar = itemView.findViewById(R.id.seekbar_id);
}
void bind(Device item) {
// Do something with the switch and u have item here
}
@Override
public void onClick(View view) { }
}
