Android卡基于位置的多种布局

时间:2016-03-10 10:05:26

标签: android adapter android-cardview

我想根据卡片在屏幕上的位置使用不同的布局。例如,我需要第一张牌(位置0使用布局first_card.xml),其他牌应使用other_cards.xml布局,并且应该水平放置(见下图(从官方谷歌网站拍摄的照片))。 enter image description here

这是我的代码

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{
    private List<CardData> mItems;
    private Context context;
    private SendInfoToCards cardDatas;
    private boolean mainMenu;
    private static final int FIRST = 1;
    private static final int SECOND = 2;

    public CardAdapter(Context c, SendInfoToCards datas, boolean main) {
        super();
        this.context = c;
        this.cardDatas = datas;
        mItems = datas.getList();
        this.mainMenu = main;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
        if(!mainMenu) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_view_card_item, viewGroup, false);
            ViewHolder viewHolder = new ViewHolder(v);
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    TextView city = (TextView) v.findViewById(R.id.tv_movie);
                    String fragmentSwitcher = city.getText().toString();
                    if (fragmentSwitcher.equals("Zemelapis")) {
                        switchFragments(0);
                    } else {
                        switchFragments(1);
                    }
                }
            });
            return viewHolder;
        } else {
            View v;
            if(position == 0){
                v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
            }else{
                v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
            }
            ViewHolder viewHolder = new ViewHolder(v);
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    TextView city = (TextView) v.findViewById(R.id.tv_movie);
                    String fragmentSwitcher = city.getText().toString();
                }
            });
            return viewHolder;
        }
    }

    private void switchFragments(int nr){
        if(nr == 0){
            Log.d("TAG", "mapo");
        } else {
            Intent intent = new Intent(context, DetailTourActivity.class);
            context.startActivity(intent);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        if(i != 0){

        } else {
            CardData data = mItems.get(i);
            viewHolder.tvMovie.setText(data.getName());
            viewHolder.imgThumbnail.setImageResource(data.getThumbnail());
        }
    }

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

    class ViewHolder extends RecyclerView.ViewHolder{
        public ImageView imgThumbnail;
        public TextView tvMovie;

        public ViewHolder(View itemView) {
            super(itemView);
            imgThumbnail = (ImageView)itemView.findViewById(R.id.img_thumbnail);
            tvMovie = (TextView)itemView.findViewById(R.id.tv_movie);
        }
    }
}

可悲的是,onCreateViewHolder方法第二个参数position始终为0.为什么?如何解决?

2 个答案:

答案 0 :(得分:2)

这是你的适配器类应该大致看起来像什么

public class CardAdapter extends RecyclerView.Adapter<RecylerView.ViewHolder>{
    private List<CardData> mItems;
    private Context context;
    private SendInfoToCards cardDatas;
    private boolean mainMenu;
    private static final int FIRST = 1;
    private static final int SECOND = 2;

    public CardAdapter(Context c, SendInfoToCards datas, boolean main) {
        super();
        this.context = c;
        this.cardDatas = datas;
        mItems = datas.getList();
        this.mainMenu = main;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
        if(type == SECOND){
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
            return new SecondViewViewHolder(v);
        } else {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
            return new FirstViewViewHolder(v);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        if(viewHolder instanceof SecondViewViewHolder){
            SecondViewViewHolder secondViewViewHolder = (SecondViewViewHolder) viewHolder;
            // bind second views
            secondViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
        } else {
            FirstViewViewHolder firstViewViewHolder = (FirstViewViewHolder) viewHolder;
            // bind firs view
            firstViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return FIRST;
        } else {
            return SECOND;
        }
    }

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

    class FirstViewViewHolder extends RecyclerView.ViewHolder{
        public ImageView imgThumbnail;
        public TextView tvMovie;

        public FirstViewViewHolder(View itemView) {
            super(itemView);
            imgThumbnail = (ImageView)itemView.findViewById(R.id.img_thumbnail);
            tvMovie = (TextView)itemView.findViewById(R.id.tv_movie);
        }
    }

    class SecondViewViewHolder extends RecyclerView.ViewHolder{
        public ImageView imgThumbnail;
        public TextView tvMovie;
        public ImageView imgThumbnail2;
        public TextView tvMovie2;

        public SecondViewViewHolder(View itemView) {
            super(itemView);
            //find viewby id
        }
    }
}

更改内容

由于recyclerview可以处理多种视图类型,您可以根据某些条件决定要扩展哪种布局。您可以通过覆盖RecylerView适配器的 getItemViewTypeMethod()来实现此目的

 @Override
 public int getItemViewType(int position) {
    if (position == 0) {
         return FIRST;
    } else {
       return SECOND;
    }
}

创建视图时。 onCreateViewHolder方法将获取视图类型。根据类型,您应该夸大适当的布局并返回相应的视图

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
   if(type == SECOND){
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
        return new SecondViewViewHolder(v);
    } else {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
        return new FirstViewViewHolder(v);
    }
}

由于涉及两个布局,我创建了两个View Holders来保存第一和第二个布局。 (FirstViewHolder&amp; SecondViewHolder)。因此,您必须将适配器的ViewHolder类型设置为基本的ViewHolder类,如下所示

public class CardAdapter extends RecyclerView.Adapter<RecylerView.ViewHolder>{
   ...
}

现在在onBindViewHolder方法中,您可以确定当前绑定的ViewHolder并相应地开展工作

 @Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    if(viewHolder instanceof SecondViewViewHolder){
        SecondViewViewHolder secondViewViewHolder = (SecondViewViewHolder) viewHolder;
        // bind second views
            secondViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
    } else {
        FirstViewViewHolder firstViewViewHolder = (FirstViewViewHolder) viewHolder;
        // bind firs view
        firstViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
    }
}

检查this以获取示例

答案 1 :(得分:1)

问题是第二个参数不是位置,而是viewType

来自docs

public abstract VH onCreateViewHolder (ViewGroup parent, int viewType)

看看public void onBindViewHolder (VH holder, int position, List<Object> payloads),这是你真正需要的