I have different ViewHolder
for different Feed
implementations. But I can't use the best practice of having each ViewHolder
corresponds to different layout id because i am reusing layout for 2 different ViewHolder
(aka. FeedWithImageHolder
and FeedWithoutImageHolder
)
class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.BaseFeedHolder>{
@NonNull
@Override
public BaseFeedHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = null;
switch (viewType){
case FeedType.FEED_WITH_IMAGE :
v = LayoutInflater.from(context).inflate(R.layout.feed_status,parent,false);
//notice that i use the same R.layout.feed_status for two different ViewHolder
return new FeedWithImageHolder(v);
case FeedType.FEED_WITHOUT_IMAGE:
v = LayoutInflater.from(context).inflate(R.layout.feed_status,parent,false);
return new FeedWithoutImageHolder(v);
case FeedType.ADS:
v = LayoutInflater.from(context).inflate(R.layout.ads,parent,false);
return new AdsHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull BaseFeedHolder holder, int position) {
//noinspection unchecked
holder.bindFeed(feeds.get(position));
}
abstract class BaseFeedHolder<T extends Feed> extends RecyclerView.ViewHolder {
BaseFeedHolder(@NonNull View itemView) {
super(itemView);
}
abstract void bindFeed(T feed);
}
class FeedWithImageHolder extends BaseFeedHolder<FeedStatus>{
FeedWithImageHolder(@NonNull View itemView) {
super(itemView);
}
@Override
void bindFeed(FeedStatus feed) {
doSomethingWithFeed(feed);
bindImage(feed.getPostImage());
}
protected void bindImage(String image){
clipImageToImageView(image);
}
}
class FeedWithoutImageHolder extends FeedWithImageHolder{
FeedWithoutImageHolder(@NonNull View itemView) {
super(itemView);
removeImageViewFromCoinstraintLayout(itemView);
}
@Override
protected void bindImage(String image) {
//void
}
}
class AdsHolder extends BaseFeedHolder<Ads>{
AdsHolder(@NonNull View itemView) {
super(itemView);
}
@Override
void bindFeed(Ads ads) {
}
}
}
Instead what I do is making Feed
have a method .getType()
so every implementation can have different type corresponding to it.
For example:
class FeedStatus implements Feed {
private String image;
@Override
public int getType() {
return (this.image == null) ? FeedType.FEED_WITHOUT_IMAGE : FeedType.FEED_WITH_IMAGE;
}
}
There is tingling worry here because I think there is code smell in there but I am not sure which one and I hope you can help me with it. Thanks