Android RecyclerView 다양한 아 이 템 레이아웃 구현 방법
14608 단어 RecyclerViewitem배치
이 RecyclerView 에 여러 가지 아 이 템 이 표시 되 어 있 습 니 다.그러면 구체 적 으로 어떻게 실현 되 는 지 알 수 있 습 니 다.사실 RecyclerView 에서 우 리 는 getItemView Type()을 다시 쓸 수 있 습 니 다.이 방법 은 하나의 매개 변수 position 에 들 어가 현재 몇 번 째 아 이 템 임 을 표시 합 니 다.그리고 우 리 는 position 을 통 해 현재 아 이 템 대상 을 얻 은 다음 에 이 아 이 템 대상 이 그런 보기 가 필요 하 다 고 판단 할 수 있 습 니 다.int 형식의 보기 표 지 를 되 돌려 주 고 onCreatView Holder 방법 에서 레이아웃 을 도입 하면 다양한 아 이 템 을 표시 할 수 있 습 니 다.이렇게 많은 예 를 들 어 구체 적 인 예 를 살 펴 보 겠 습 니 다.
@Override
public int getItemViewType(int position) {
if(list.size() == 0){
return EMPTY_VIEW;
} else if(list.get(position) == null){
return PROGRESS_VIEW;
} else if(list.get(position).getType().equals(News.IMAGE_NEWS)){
return IMAGE_VIEW;
} else {
return super.getItemViewType(position);
}
}
먼저 getItemView Type 이라는 방법 을 다시 썼 습 니 다.이 방법 에서 position 에 따라 item 대상 에 대해 판단 을 했 습 니 다.만약 에 item 대상 의 집합 크기 가 비어 있 으 면 빈 view 표지(여기 가 1)로 돌아 갑 니 다.만약 에 item 대상 이 null 이면 진도 표 지 를 되 돌려 줍 니 다.이것 은 주로 드 롭 다운 로드 를 실현 하 는 데 사 용 됩 니 다.만약 에 item 대상 유형 이 이미지 유형 에 속 하면그림 형식 에 대응 하 는 아 이 템 을 되 돌려 줍 니 다.이것 이 바로 효과 그림 의 첫 번 째 아 이 템 유형 입 니 다.그렇지 않 으 면 다른 유형,즉 효과 그림 의 다른 아 이 템 레이아웃 입 니 다.그리고 우 리 는 onCreatView Holder 에서 구체 적 으로 모든 유형 에 레이아웃 을 도입 합 니 다.
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if(viewType == PROGRESS_VIEW){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item, parent, false);
return new ProgressViewHolder(view);
} else if(viewType == EMPTY_VIEW){
return null;
} else if(viewType == IMAGE_VIEW){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item, parent, false);
return new ImageViewHolder(view);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
return new NewsViewHolder(view);
}
}
위의 코드 는 모든 view Type 에 해당 하 는 레이아웃 을 구체 적 으로 도입 하 는 것 입 니 다.그러면 기본적으로 여러 가지 item 레이아웃 을 실현 할 수 있 습 니 다.그러나 이것 만 으로 는 부족 합 니 다.우 리 는 모든 item 에 데 이 터 를 설정 해 야 하기 때문에 모든 item 에 VIEwHolder 를 써 서 item 에 데 이 터 를 표시 해 야 합 니 다.
class NewsViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.news_title)TextView title;
@BindView(R.id.news_digest)TextView digest;
@BindView(R.id.news_time)TextView time;
@BindView(R.id.news_src)ImageView image;
public NewsViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
class ImageViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.news_title) TextView title;
@BindView(R.id.image_left) ImageView imageLeft;
@BindView(R.id.image_right) ImageView imageRight;
@BindView(R.id.image_middle) ImageView imageMiddle;
@BindView(R.id.news_time) TextView time;
public ImageViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
class ProgressViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.progressBar) ProgressBar progressBar;
@BindView(R.id.textView) TextView textView;
public ProgressViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
위 는 item 에 대응 하 는 몇 개의 ViewHolder 입 니 다.viewHolder 가 그 대상 에 속 하 는 지 판단 한 다음 에 onBindViewHolder 에서 해당 하 는 ViewHolder 에 따라 컨트롤 에 데 이 터 를 설정 하고 표시 합 니 다.
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.onItemClick(v, position);
}
});
if(holder instanceof NewsViewHolder){
NewsViewHolder viewHolder = (NewsViewHolder)holder;
viewHolder.title.setText(list.get(position).getTitle());
viewHolder.time.setText(list.get(position).getTime());
/**
* Glide
*/
Glide.with(context).load(list.get(position).getImageUrl().get(0))
.override(dpToPx(72), dpToPx(72)).centerCrop().into(viewHolder.image);
if(list.get(position).getType().equals(News.TEXT_NEWS)){
viewHolder.digest.setText(list.get(position).getDigest());
} else {
viewHolder.digest.setText("");
}
} else if(holder instanceof ImageViewHolder){
ImageViewHolder viewHolder = (ImageViewHolder)holder;
viewHolder.title.setText(list.get(position).getTitle());
viewHolder.time.setText(list.get(position).getTime());
setItemImage(viewHolder, list, position);
} else if(holder instanceof ProgressViewHolder){
ProgressViewHolder viewHolder = (ProgressViewHolder)holder;
viewHolder.progressBar.setIndeterminate(true);
}
}
전체 과정 은 기본적으로 이 렇 습 니 다.이런 방식 은 프로젝트 에 자주 사 용 됩 니 다.우 리 는 이렇게 처리 할 수 있 습 니 다.드 롭 다운 로드 가 더 많 으 면 이렇게 이 루어 집 니 다.데 이 터 를 불 러 온 다음 에 대상 집합 에 null 을 전송 한 다음 에 null 이 나타 나 면 progressBar 레이아웃 을 불 러 올 것 이 라 고 판단 합 니 다.게다가 Google 공식 Swipe RefreshLayout,드 롭 다운 새로 고침,드 롭 다운 로드 가 완료 되 었 습 니 다.사실 쉬 워 요.그리고 약간 Material Design 느낌 도 있어 요.Adapter 의 모든 코드 를 보 세 요.
package com.zmt.e_read.Adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.zmt.e_read.Module.News;
import com.zmt.e_read.Module.OnItemClickListener;
import com.zmt.e_read.R;
import com.zmt.e_read.Utils.ProgressViewHolder;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by Dangelo on 2016/9/27.
*/
public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int EMPTY_VIEW = 1;
private final int PROGRESS_VIEW = 2;
private final int IMAGE_VIEW = 3;
private Context context;
private List<News> list;
private OnItemClickListener clickListener;
public NewsAdapter(Context context, List<News> list, OnItemClickListener clickListener) {
this.context = context;
this.list = list;
this.clickListener = clickListener;
}
public void addOnItemClickListener(OnItemClickListener clickListener){
this.clickListener = clickListener;
}
@Override
public int getItemViewType(int position) {
if(list.size() == 0){
return EMPTY_VIEW;
} else if(list.get(position) == null){
return PROGRESS_VIEW;
} else if(list.get(position).getType().equals(News.IMAGE_NEWS)){
return IMAGE_VIEW;
} else {
return super.getItemViewType(position);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if(viewType == PROGRESS_VIEW){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item, parent, false);
return new ProgressViewHolder(view);
} else if(viewType == EMPTY_VIEW){
return null;
} else if(viewType == IMAGE_VIEW){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item, parent, false);
return new ImageViewHolder(view);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
return new NewsViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.onItemClick(v, position);
}
});
if(holder instanceof NewsViewHolder){
NewsViewHolder viewHolder = (NewsViewHolder)holder;
viewHolder.title.setText(list.get(position).getTitle());
viewHolder.time.setText(list.get(position).getTime());
/**
* Glide
*/
Glide.with(context).load(list.get(position).getImageUrl().get(0))
.override(dpToPx(72), dpToPx(72)).centerCrop().into(viewHolder.image);
if(list.get(position).getType().equals(News.TEXT_NEWS)){
viewHolder.digest.setText(list.get(position).getDigest());
} else {
viewHolder.digest.setText("");
}
} else if(holder instanceof ImageViewHolder){
ImageViewHolder viewHolder = (ImageViewHolder)holder;
viewHolder.title.setText(list.get(position).getTitle());
viewHolder.time.setText(list.get(position).getTime());
setItemImage(viewHolder, list, position);
} else if(holder instanceof ProgressViewHolder){
ProgressViewHolder viewHolder = (ProgressViewHolder)holder;
viewHolder.progressBar.setIndeterminate(true);
}
}
public void setItemImage(ImageViewHolder viewHolder, List<News> list, int position){
viewHolder.imageMiddle.setVisibility(View.VISIBLE);
viewHolder.imageRight.setVisibility(View.VISIBLE);
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
if(list.get(position).getImageUrl().size() == 1){
Glide.with(context).load(list.get(position).getImageUrl().get(0))
.override(displayMetrics.widthPixels - dpToPx(10), dpToPx(90))
.centerCrop().into(viewHolder.imageLeft);
viewHolder.imageMiddle.setVisibility(View.GONE);
viewHolder.imageRight.setVisibility(View.GONE);
} else if(list.get(position).getImageUrl().size() == 2){
int imageWidth = (displayMetrics.widthPixels - dpToPx(20)) / 2;
Glide.with(context).load(list.get(position).getImageUrl().get(0))
.override(imageWidth, dpToPx(90))
.centerCrop().into(viewHolder.imageLeft);
Glide.with(context).load(list.get(position).getImageUrl().get(1))
.override(imageWidth, dpToPx(90))
.centerCrop().into(viewHolder.imageMiddle);
viewHolder.imageRight.setVisibility(View.GONE);
} else if(list.get(position).getImageUrl().size() >= 3){
int imageWidth = (displayMetrics.widthPixels - dpToPx(30)) / 3;
Glide.with(context).load(list.get(position).getImageUrl().get(0))
.override(imageWidth, dpToPx(90))
.centerCrop().into(viewHolder.imageLeft);
Glide.with(context).load(list.get(position).getImageUrl().get(1))
.override(imageWidth, dpToPx(90))
.centerCrop().into(viewHolder.imageMiddle);
Glide.with(context).load(list.get(position).getImageUrl().get(2))
.override(imageWidth, dpToPx(90))
.centerCrop().into(viewHolder.imageRight);
}
}
@Override
public int getItemCount() {
return list.size();
}
public int dpToPx(float dp){
float px = context.getResources().getDisplayMetrics().density;
return (int)(dp * px + 0.5f);
}
class NewsViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.news_title)TextView title;
@BindView(R.id.news_digest)TextView digest;
@BindView(R.id.news_time)TextView time;
@BindView(R.id.news_src)ImageView image;
public NewsViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
class ImageViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.news_title) TextView title;
@BindView(R.id.image_left) ImageView imageLeft;
@BindView(R.id.image_right) ImageView imageRight;
@BindView(R.id.image_middle) ImageView imageMiddle;
@BindView(R.id.news_time) TextView time;
public ImageViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
class ProgressViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.progressBar) ProgressBar progressBar;
@BindView(R.id.textView) TextView textView;
public ProgressViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
프로젝트 주소:https://github.com/xiyouZmt/E-Read마지막 으로 왜 ListView 대신 RecyclerView 를 사 용 했 는 지 말씀 드 리 겠 습 니 다.
ListView 를 사용 해 본 사람들 은 모두 알 고 있 습 니 다.ListView 에서 보기 캐 시 를 다시 사용 하려 면 getView()방법 에서 convertView 가 비어 있 는 지 수 동 으로 판단 해 야 합 니 다.비어 있 지 않 으 면 보기 캐 시 를 다시 사용 하고 비어 있 으 면 보 기 를 다시 불 러 옵 니 다.RecyclerView 는 ListView 의 Adapter 를 다시 봉인 한 것 과 같 습 니 다.ListView 를 수 동 으로 캐 시 여 부 를 판단 하 는 코드 를 RecyclerView 내부 에 봉 인 했 습 니 다.이 부분의 논 리 를 볼 수 없 게 하려 면 getItemCount()방법 을 통 해 RecyclerView 에 몇 가지 데이터 가 있 는 지 알려 주 고 onCreate ViewHolder()에 item 레이아웃 을 불 러 와 뷰 Holder 를 예화 한 다음 에 onBindViewHolder()에서 데이터 의 바 인 딩 을 완성 하면 됩 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Android】RecyclerView+RadioButton의 작성RadioGroup을 사용하지 않고 작성합니다. RecyclerView 배치 activity_main.xml RadioButton 배치 view_item.xml RecyclerView 용 어댑터 작성. 어느 버튼을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.