为什么bindViewHolder接受一个位置作为参数? [英] Why does bindViewHolder accept a position as an argument?

查看:153
本文介绍了为什么bindViewHolder接受一个位置作为参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解该设计什么 RecylerView.adapter 。在 onCreateViewHolder 方法接受一个视图类型作为参数。

  onCreateViewHolder(ViewGroup中的父母,INT viewType)


  当RecyclerView需要的新RecyclerView.ViewHolder名为


  给定类型重新present一个项目。


此视图类型在getItemViewType映射

  getItemViewType(INT位置)


  

返回的项目的视图类型在位置的视图目的
  回收再利用。


最后,当结合ViewHolder bindViewHolder被称为

  onBindViewHolder(VH持有人,INT位置)


  

由RecyclerView调用在指定位置显示的数据。


为什么位置onBindViewHolder参数?我的理解是,在发送给onCreateViewHolder的viewType允许开发者创建基于视图类型适当ViewHolder。如果是这种情况,在onBindViewHolder位置是多余的和不必要的。

我是不是想用正确的RecyclerView.adapter类的?这让我怀疑其传递给onBindViewHolder,这似乎尖叫要使用的位置参数我的理解,但在我目前的实现真的没有必要,因为我ViewHolders所使用的是从位置映射视图类型已创建


解决方案

  

为什么位置onBindViewHolder参数?


所以,你知道什么样的数据绑定到 ViewHolder RecyclerView 旨在显示的数据的集合;一个 ViewHolder 从收集他们的意见,结合一个项目。


  

如果是这种情况,在onBindViewHolder位置是多余的和不必要的。


只有当你总是会使用 RecyclerView 与零个或一个项目集合模型数据,在这种情况下,你不应该使用 RecyclerView


  

我ViewHolders所使用的是从位置映射视图类型已经创建


的视图类型是次明显不同的结构,如头和信息。视图类型是独立的位置,这就是为什么位置没有传递到 onCreateViewHolder()

因此​​,举例来说,假设你想从Lorem存有列表中显示的25拉丁词一个垂直滚动列表。默认的是,有一个视图类型(即,不重写 getItemViewType()),以及你们的话绑定到的TextView (或其他)的列表行 onBindViewHolder()

如果,在你实现一个25字的列表 RecyclerView ,您使用的是25视图类型中,最有可能你正在做的是错误的。在那里,可能依稀是适当的唯一情况是,如果各行会在结构上非常不同的(第一行是的TextView ,第二行是的ImageButton ,第三行是的ImageView 加<​​/ code> A 开关等)。

作为一个例子,这里是承载一个活动 RecyclerView 来显示一个25字的列表:

  / ***
  版权所有(c)2008至2015年CommonsWare,LLC
  在Apache许可2.0版(简称许可证);你不可以
  使用这个文件除了在遵守许可。你可以得到一个副本
  在http://www.apache.org/licenses/LICENSE-2.0许可证。除非需要
  适用法律或书面同意,根据分布式软件
  许可证分布在原样的基础,没有担保或条件
  任何形式的,无论是前preSS或暗示的保证。查看许可证的具体
  根据许可证的语言管辖权限和限制。  从_The忙codeR指南到Android Development_
    https://commonsware.com/Android
* /包com.commonsware.android.recyclerview.simplelist;进口android.os.Bundle;
进口android.support.v7.widget.LinearLayoutManager;
进口android.support.v7.widget.RecyclerView;
进口android.view.View;
进口android.view.ViewGroup;
进口android.widget.ArrayAdapter;
进口android.widget.ImageView;
进口android.widget.TextView;公共类MainActivity扩展RecyclerViewActivity {
  私有静态最后的String []项目= {排版,文字,悲
          坐,阿梅特,
          consectetuer,adipiscing,ELIT,morbi,VEL,
          ligula,履历,arcu,aliquet,油树,
          etiam,韦尔,ERAT,placerat,赌注,
          porttitor,sodales,pellentesque,augue,普鲁斯};  @覆盖
  公共无效的onCreate(捆绑冰柱){
    super.onCreate(冰柱);    setLayoutManager(新LinearLayoutManager(本));
    setAdapter(新IconicAdapter());
  }  类IconicAdapter扩展RecyclerView.Adapter&LT; RowHolder&GT; {
    @覆盖
    公共RowHolder onCreateViewHolder(ViewGroup中的父母,INT viewType){
      返程(新RowHolder(getLayoutInflater()
                            .inflate(R.layout.row,父母,FALSE)));
    }    @覆盖
    公共无效onBindViewHolder(RowHolder持有人,INT位置){
      holder.bindModel(项目[位置]);
    }    @覆盖
    公众诠释getItemCount(){
      回报(items.length);
    }
  }  静态类RowHolder扩展RecyclerView.ViewHolder {
    TextView的标签= NULL;
    TextView的大小= NULL;
    ImageView的图标= NULL;
    字符串模板= NULL;    RowHolder(查看行){
      超(行);      标签=(TextView中)row.findViewById(R.id.label);
      大小=(TextView中)row.findViewById(R.id.size);
      图标=(ImageView的)row.findViewById(R.id.icon);      模板= size.getContext()的getString(R.string.size_template)。
    }    无效bindModel(字符串项){
      label.setText(项目);
      size.setText(的String.format(模板,item.length()));      如果(item.length()→4){
        icon.setImageResource(R.drawable.delete);
      }
      其他{
        icon.setImageResource(R.drawable.ok);
      }
    }
  }
}

这延伸<一个href=\"https://github.com/commonsguy/cw-omnibus/blob/master/RecyclerView/SimpleList/src/com/commonsware/android/recyclerview/simplelist/RecyclerViewActivity.java\"相对=nofollow>一个简单的 RecyclerViewActivity 我拼凑起来作为一个对口 ListActivity ,但多数逻辑是在这里,在适配器 ViewHolder 。您还可以查看整个项目和的〜20 RecyclerView 样本项目的整体如果需要的话。

I am trying to understand what the design is for RecylerView.adapter. The onCreateViewHoldermethod accepts a view type as an argument.

onCreateViewHolder(ViewGroup parent, int viewType)

Called when RecyclerView needs a new RecyclerView.ViewHolder of the given type to represent an item.

This view type is mapped in getItemViewType

getItemViewType(int position)

Return the view type of the item at position for the purposes of view recycling.

And finally when binding the ViewHolder bindViewHolder is called

onBindViewHolder(VH holder, int position)

Called by RecyclerView to display the data at the specified position.

Why is position a parameter in onBindViewHolder? My understanding is that the viewType sent in to onCreateViewHolder allows developers to create an appropriate ViewHolder based on the view type. If this is the case, the position in onBindViewHolder is redundant and unnecessary.

Am I thinking about use of the RecyclerView.adapter class correctly? It makes me question my understanding having the position parameter passed to onBindViewHolder, which seems to scream to be used, but which in my current implementations really doesn't have a need since my ViewHolders are already created using a view type which was mapped from position.

解决方案

Why is position a parameter in onBindViewHolder?

So you know what data to bind to the ViewHolder. RecyclerView is designed to show a collection of data; a ViewHolder binds one item from that collection to its views.

If this is the case, the position in onBindViewHolder is redundant and unnecessary.

Only if you will always use RecyclerView with a zero- or one-item collection of model data, in which case you should not be using RecyclerView.

my ViewHolders are already created using a view type which was mapped from position

The view type is for views of distinctly different structure, such as headers and details. The view type is independent of position, which is why the position is not passed into onCreateViewHolder().

So, for example, suppose you want to show a vertical-scrolling list of 25 Latin words from a lorem ipsum list. The default is that there is one view type (i.e., you do not override getItemViewType()), and you bind the word to the TextView (or whatever) for the list row in onBindViewHolder().

If, in your implementation of a 25-word-list RecyclerView, you are using 25 view types, most likely you are doing it wrong. The only case where that might vaguely be appropriate is if each row will be very different in structure (first row is a TextView, second row is an ImageButton, third row is an ImageView plus a Switch, etc.).

As an example, here is an activity that hosts a RecyclerView to show a 25-word list:

/***
  Copyright (c) 2008-2015 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain   a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    https://commonsware.com/Android
*/

package com.commonsware.android.recyclerview.simplelist;

import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends RecyclerViewActivity {
  private static final String[] items={"lorem", "ipsum", "dolor",
          "sit", "amet",
          "consectetuer", "adipiscing", "elit", "morbi", "vel",
          "ligula", "vitae", "arcu", "aliquet", "mollis",
          "etiam", "vel", "erat", "placerat", "ante",
          "porttitor", "sodales", "pellentesque", "augue", "purus"};

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    setLayoutManager(new LinearLayoutManager(this));
    setAdapter(new IconicAdapter());
  }

  class IconicAdapter extends RecyclerView.Adapter<RowHolder> {
    @Override
    public RowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      return(new RowHolder(getLayoutInflater()
                            .inflate(R.layout.row, parent, false)));
    }

    @Override
    public void onBindViewHolder(RowHolder holder, int position) {
      holder.bindModel(items[position]);
    }

    @Override
    public int getItemCount() {
      return(items.length);
    }
  }

  static class RowHolder extends RecyclerView.ViewHolder {
    TextView label=null;
    TextView size=null;
    ImageView icon=null;
    String template=null;

    RowHolder(View row) {
      super(row);

      label=(TextView)row.findViewById(R.id.label);
      size=(TextView)row.findViewById(R.id.size);
      icon=(ImageView)row.findViewById(R.id.icon);

      template=size.getContext().getString(R.string.size_template);
    }

    void bindModel(String item) {
      label.setText(item);
      size.setText(String.format(template, item.length()));

      if (item.length()>4) {
        icon.setImageResource(R.drawable.delete);
      }
      else {
        icon.setImageResource(R.drawable.ok);
      }
    }
  }
}

This extends a simple RecyclerViewActivity I cobbled together as a counterpart to ListActivity, but most of the logic is here, in the Adapter and ViewHolder. You can also view the full project, and ~20 RecyclerView sample projects overall, if desired.

这篇关于为什么bindViewHolder接受一个位置作为参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆