Это можно сделать с помощью метода RecyclerView.Adapter
getItemViewType(int position)
. Он получает позицию адаптера и возвращает int viewType , который можно использовать позже в onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
для надувания макета в соответствии с viewType
. Вы можете узнать больше об этом здесь . Ниже я покажу, как мне установить LayoutParams
для каждого элемента в отдельности:
Интерфейс для пометки объекта как объекта с помощью LayoutParams
:
interface Parameterized {
RecyclerView.LayoutParams getParams();
}
Модель класса:
public class Comment implements Parameterized {
private String content;
private RecyclerView.LayoutParams params;
public Comment(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public RecyclerView.LayoutParams getParams() {
return params;
}
public void setParams(RecyclerView.LayoutParams params) {
this.params = params;
}
}
Используя метод setParams()
, мы можем установить RecyclerView.LayoutParams
для объекта комментария, который позже может быть использован адаптером.
Адаптер:
public class CommentRecyclerAdapter extends RecyclerView.Adapter<CommentRecyclerAdapter.MyViewHolder> {
private List<Comment> comments = new ArrayList<>();
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_name, parent, false);
v.setLayoutParams(comments.get(viewType).getParams());
return new MyViewHolder(v);
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Comment comment = comments.get(position);
holder.tvComment.setText(comment.getContent());
}
@Override
public int getItemCount() {
return comments.size();
}
public void updateComments(List<Comment> comments) {
this.comments = comments;
notifyDataSetChanged();
}
public void addComment(Comment comment) {
comments.add(comment);
notifyItemInserted(comments.size());
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvComment;
MyViewHolder(@NonNull View itemView) {
super(itemView);
tvComment = itemView.findViewById(R.id.tv_comment);
}
}
}
Использование в упражнении / фрагменте в качестве примера:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
recyclerView = findViewById(R.id.rv_comments);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new CommentRecyclerAdapter();
recyclerView.setAdapter(adapter);
adapter.updateComments(getGeneratedComments());
Comment comment = new Comment("Added comment");
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
params.rightMargin = 30;
params.leftMargin = 30;
params.topMargin = 50;
comment.setParams(params);
adapter.addComment(comment);
}
private List<Comment> getGeneratedComments() {
List<Comment> comments = new ArrayList<>();
for (int i = 1; i < 7; i++) {
Comment comment = new Comment("Comment " + i);
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
params.topMargin = 20 * i;
comment.setParams(params);
comments.add(comment);
}
return comments;
}
Метод адаптера updateComments(List<Comment> comments)
обновляет весь список, а addComment(Comment comment)
добавляет элемент с параметрами в конце списка.
Вот как это выглядит:
