如何使用单个适配器在Recycler视图中加载不同的布局

时间:2017-08-25 14:15:09

标签: android android-recyclerview

感谢您抽出时间阅读我的问题。 我一直在一个项目中工作,我必须在recyclerView中加载很多布局。

详细说明,包含

的Recycler列表视图
  • -----电影布局-----(在顶部)
  • -----剧院布局-----(电影布局下方)
  • -----大片-----(剧院布局下方)

我的设计是这样的,

  • 具有回收者视图的活动
  • 一个CommonAdapter
  • 三个Pojo课程
  • 三种布局

我使用的代码,

我的Pojo(所有三个pojo的设计都一样)

public class Movie {
    String title, genre, year;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public Movie(String title, String genre, String year) {
        this.title = title;
        this.genre = genre;
        this.year = year;
    }
}

我的RecyclerView适配器

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

    private List<Movie> moviesList;
    private List<Movie1> moviesList1;

    final int Movie = 0, Movie1 = 1;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;

        public MyViewHolder(View view, int viewType) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
        }
    }

    public class MyViewHolder2 extends RecyclerView.ViewHolder {
        public TextView title, year, genre;

        public MyViewHolder2(View view, int Viewtype) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
        }


    }

    @Override
    public int getItemViewType(int position) {

        if (moviesList.get(position) instanceof Movie) {
            return Movie;
        } else if (moviesList1.get(position) instanceof Movie1) {
            return Movie1;
        }
        return -1;
    }

    public MoviesAdapter(List<Movie> moviesList, List<Movie1> moviesList1) {
        this.moviesList = moviesList;
        this.moviesList1 = moviesList1;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v;
        MyViewHolder vh = null;

        // create a new view
        switch (viewType) {
            case Movie: //This would be the header view in my Recycler
                System.out.println("This is movie");
                v = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.movie_list_row, parent, false);
                vh = new MyViewHolder(v, viewType);
                return vh;

            case Movie1: //This would be the header view in my Recycler
                System.out.println("This is movie1");
                v = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.movie_row, parent, false);
                vh = new MyViewHolder(v, viewType);
                return vh;

            default: //This would be the normal list with the pictures of the places in the world
                return vh;
        }
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
       /* if (position == 0) {
            Movie movie = moviesList.get(position);
            holder.title.setText(movie.getTitle());
            holder.genre.setText(movie.getTitle());
            holder.year.setText(movie.getTitle());
            //this means it is beyond the headerview now as it is no longer 0. For testing purposes, I'm alternating between two pics for now
        } else if (position == 1) {
            Movie1 movie = moviesList1.get(position);
            holder.title.setText(movie.getTitle());
            holder.genre.setText(movie.getGenre());
            holder.year.setText(movie.getYear());

        }*/

        switch (holder.getItemViewType()) {
            case Movie:
                MyViewHolder vh1 = (MyViewHolder) holder;
                Movie movie = (Movie) moviesList.get(position);
                vh1.title.setText(movie.getTitle());
                vh1.genre.setText(movie.getGenre());
                vh1.year.setText(movie.getYear());

                break;
            case Movie1:
                MyViewHolder vh2 = (MyViewHolder) holder;
                Movie1 movie1=(Movie1)moviesList1.get(position);
                vh2.title.setText(movie1.getTitle());
                vh2.year.setText(movie1.getYear());
                vh2.genre.setText(movie1.getGenre());

                break;
            default:
                break;
        }

    }

    @Override
    public int getItemCount() {
        return moviesList.size();
    }

我的活动代码

 recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        mAdapter = new MoviesAdapter(movieList, movieList1);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);

        prepareMovieData();
        prepareMovieData1();

并且prepareMovieData()方法代码,

private void prepareMovieData() {
        Movie movie = new Movie("Mad Max: Fury Road", "Action & Adventure", "2015");
        movieList.add(movie);

        movie = new Movie("Inside Out", "Animation, Kids & Family", "2015");
        movieList.add(movie);

        movie = new Movie("Star Wars: Episode VII - The Force Awakens", "Action", "2015");
        movieList.add(movie);

        movie = new Movie("Shaun the Sheep", "Animation", "2015");
        movieList.add(movie);}

运行程序后,仅在我的回收站视图中加载第一个布局。任何帮助对我学习这些东西都会有很大帮助!

谢谢!

2 个答案:

答案 0 :(得分:3)

SimpleItemRecyclerViewAdapter替换为更多ComplexRecyclerViewAdapter,以便根据项目视图类型对不同类型的布局进行充气。 例如,您的RecyclerViewActivity需要包含对象列表,如下所示:

private ArrayList<Object> getSampleArrayList() {
      ArrayList<Object> items = new ArrayList<>();
      items.add(new Movie ("Mad Max: Fury Road", "Action & Adventure", "2015"));
      items.add(new Theatres ("Something", "something"));
      items.add(new Blockbuster ("Something else", "Something else"));
      return items;
  }

之后你需要三个类和布局,如MovieHolder.Java和movie_layout.java,如下所示: 公共类MovieHolder扩展了RecyclerView.ViewHolder {

private TextView title, gener,year;

public MovieHolder (View v) {
    super(v);
    title= (TextView) v.findViewById(R.id.title);
    gener= (TextView) v.findViewById(R.id.gener);
    year= (TextView) v.findViewById(R.id.year);
}

public TextView getTitle() {
    return title;
}

public void setTitle(TextView title) {
    this.title= title;
}

public TextView getGener() {
    return gener;
}

public void setGener(TextView gener) {
    this.gener= gener;
}

public TextView getYear() {
        return year;
    }

    public void setYear(TextView year) {
        this.label2 = year;
    }



}

依旧......

之后你需要创建 ComplexRecyclerViewAdapter

public class ComplexRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    // The items to display in your RecyclerView
    private List<Object> items;

    private final int MOVIE= 0,THEATERS=1 , BLOCKBUSTER = 2;

    // Provide a suitable constructor (depends on the kind of dataset)
    public ComplexRecyclerViewAdapter(List<Object> items) {
        this.items = items;
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return this.items.size();
    }

    @Override
    public int getItemViewType(int position) {
           if (items.get(position) instanceof Movie) {
               return MOVIE;
         } else if (items.get(position) instanceof Theatrs ) {
               return THEATERS;
         }else if (items.get(position) instanceof Blockbuster ) {
               return BLOCKBUSTER ;
      }
         return -1;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup   viewGroup, int viewType) {
              RecyclerView.ViewHolder viewHolder;
  LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

  switch (viewType) {
      case MOVIE:
          View v1 = inflater.inflate(R.layout.movie_viewholder, viewGroup, false);
          viewHolder = new ViewHolder1(v1);
          break;
      case THEATERS:
          View v2 = inflater.inflate(R.layout.theater_viewholder2, viewGroup, false);
          viewHolder = new ViewHolder2(v2);
          break;

      case BLOCKBUSTER :
          View v3 = inflater.inflate(R.layout.layout_blockbuster, viewGroup, false);
          viewHolder = new ViewHolder3(v3);
          break;
      default:
          View v = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
          viewHolder = new RecyclerViewSimpleTextViewHolder(v);
          break;
  }
  return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
               switch (viewHolder.getItemViewType()) {
      case MOVIE:
          ViewHolder1 vh1 = (ViewHolder1) viewHolder;
          configureViewHolder1(vh1, position);
          break;
      case THEATERS:
          ViewHolder2 vh2 = (ViewHolder2) viewHolder;
          configureViewHolder2(vh2, position);
          break;

      case BLOCKBUSTER :
          ViewHolder3 vh3 = (ViewHolder3) viewHolder;
          configureViewHolder3(vh3, position);
          break;
      default:
          RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
          configureDefaultViewHolder(vh, position);
          break;
  }
    }
}

以下方法用于配置各个RecyclerView.ViewHolder对象:

private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) {
      vh.getLabel().setText((CharSequence) items.get(position));
  }

  private void configureViewHolder1(ViewHolder1 vh1, int position) {
      Movie movie= (Movie ) items.get(position);
      if (movie!= null) {
          vh1.getTitle().setText("Name: " + movie.title);
          vh1.getGener().setText("Gener: " + movie.gener);
          vh1.getYear().setText("Year: " + movie.year);
      }
  }
.
.
.
//and same for other 2

在您运行该计划之前,最后一个重要的变化是更改bindDataToAdapter中的RecyclerViewActivity方法以设置ComplexRecyclerViewAdapter而不是SimpleItemRecyclerViewAdapter,如下所示:

  private void bindDataToAdapter() {
      // Bind adapter to recycler view object
      recyclerView.setAdapter(new ComplexRecyclerViewAdapter(getSampleArrayList()));
  }

答案 1 :(得分:0)

首先检查正常布局并正确连接或不查看布局的xml代码。

我的主要嫌疑人是getItemCount()方法,你只返回一个列表的计数,我在recyclerview中看到了多个布局的许多其他实现,其中大多数使用单个列表并将一些字段设置为null并在onBindviewholder检索中只有特定布局需要的字段,希望这会有所帮助。

 List<CityEvent> list = new ArrayList<>();
    list.add(new CityEvent("London", null, CityEvent.CITY_TYPE));
    list.add(new CityEvent("Droidcon", "Droidcon in London", CityEvent.EVENT_TYPE));
    list.add(new CityEvent("Some event", "Some event in London", CityEvent.EVENT_TYPE));
    list.add(new CityEvent("Amsterdam", null, CityEvent.CITY_TYPE));
    list.add(new CityEvent("Droidcon", "Droidcon in Amsterdam", CityEvent.EVENT_TYPE));
    list.add(new CityEvent("Berlin", null, CityEvent.CITY_TYPE));
    list.add(new CityEvent("Droidcon", "Droidcon in Berlin", CityEvent.EVENT_TYPE));

 @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    CityEvent object = mList.get(position);
    if (object != null) {
        switch (object.getType()) {
            case CITY_TYPE:
                ((CityViewHolder) holder).mTitle.setText(object.getName());
                break;
            case EVENT_TYPE:
                ((EventViewHolder) holder).mTitle.setText(object.getName());
                ((EventViewHolder) holder).mDescription.setText(object.getDescription());
                break;
        }
    }
}
@Override
public int getItemCount() {
    if (mList == null)
        return 0;
    return mList.size();
}