It's pretty straight-forward to translate your ListView adapter to a RecyclerView.Adapter - I've written skeletons for both implementations below:
private static class MyRecyclerViewAdapter extends RecyclerView.Adapter<CustomViewHolder> {
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CustomView view = createNewCustomView();
return new CustomViewHolder(view);
}
private CustomView createNewCustomView() {
// whatever you need to do to create - I would suggest create from XML rather new'ing up directly
return null;
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// bind the data
DataModel dataModel = getModelForPosition(position);
holder.getCustomView().showView(dataModel, position);
}
private DataModel getModelForPosition(int position) {
// TODO: however you did getModelForPosition(int)
return null;
}
@Override
public int getItemCount() {
// TODO: same as getCount()
return 0;
}
}
private static class CustomViewHolder extends RecyclerView.ViewHolder {
public CustomViewHolder(CustomView itemView) {
super(itemView);
}
CustomView getCustomView() {
return ((CustomView) itemView);
}
}
private static class MyListViewAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO: return correct list size
return 0;
}
@Override
public DataModel getItem(int position) {
// TODO: however you did getModelForPosition(int)
return null;
}
@Override
public long getItemId(int position) {
// however you do
return 0;
}
@Override
public View getView(int position, View containerRow, ViewGroup parent) {
CustomView customView = ((CustomView) containerRow);
if (customView == null) {
customView = createNewCustomView();
}
// could just use getItem(int) here
DataModel dataModel = getModelForPosition(position);
// would it ever be null? if so, you'll have a blank list item
if (dataModel != null) {
customView.showView(dataModel.getSingleDcyde(), position);
}
return customView;
}
private CustomView createNewCustomView() {
// whatever you need to do to create - I would suggest create from XML rather new'ing up directly
return null;
}
private DataModel getModelForPosition(int position) {
return getItem(position);
}
}
private static class DataModel {
Object getSingleDcyde() {
// whatever this is
return null;
}
}
private static class CustomView extends View {
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void showView(Object singleDcyde, int position) {
// bind
}
}
What is the best way to keep design in sync with RecyclerView philosophy.
The philosophy behind RecyclerView is separation of concerns; the RecyclerView is responsible only for managing view recycling, the LayoutManager will decide how views are measured and positioned, the ViewHolder is an attempt to force the ViewHolder pattern (an approach to avoid multiple unnecessary calls to findViewById()
), and the RecyclerView.Adapter is the glue that hooks your data up.
You're now forced to use the ViewHolder class. The idea is do all your findViewById()
calls only once per inflated layout (whether or not this call is slow enough to bother doing is debated), e.g.:
private static final class CustomViewHolder extends RecyclerView.ViewHolder {
private final TextView titleTextView;
private final ImageView avatarImageView;
public CustomViewHolder newInstance(CustomView itemView) {
return new CustomViewHolder(
itemView,
((TextView) itemView.findViewById(R.id.title_text_view)),
((ImageView) itemView.findViewById(R.id.avatar_image_view))
);
}
private CustomViewHolder(CustomView itemView, TextView titleTextView, ImageView avatarImageView) {
super(itemView);
this.titleTextView = titleTextView;
this.avatarImageView = avatarImageView;
}
public void setTitle(String title) {
titleTextView.setText(title);
}
public void setAvatar(Drawable avatar) {
avatarImageView.setImageDrawable(avatar);
}
}
Actually, since you're using a custom View, it's very likely (I hope), that you're already avoiding multiple calls to findViewById(int)
by using the HolderView pattern. In which case you can rebel against the tyranny of mandated ViewHolder usage by treating it as necessary evil:
private static final class CustomViewHolder extends RecyclerView.ViewHolder {
public CustomViewHolder(CustomView itemView) {
super(itemView);
}
}
...
...
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
Foo foo = getFoo(position);
((CustomView) holder.itemView).myCustomBindMethod(foo);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…