代码之家  ›  专栏  ›  技术社区  ›  David

Android卡基于位置的多种布局

  •  1
  • David  · 技术社区  · 10 年前

    我想根据卡片在屏幕上的位置使用不同的布局。例如,我需要第一张卡(位置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 回复  |  直到 10 年前
        1
  •  2
  •   Much Overflow    10 年前

    下面是您的适配器类的大致外观

    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适配器的

     @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);
        }
    }
    

    由于涉及两个布局,我创建了两个视图夹持器来容纳第一个和第二个布局。(FirstViewHolder和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 例如

        2
  •  1
  •   archived    10 年前

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

    docs :

    public abstract VH onCreateViewHolder (ViewGroup parent, int viewType)
    

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

    推荐文章