如何在 RecyclerView 中显示 ArrayList?

How to display an ArrayList in a RecyclerView?

我需要添加一个 Activity,我可以在其中列出 ArrayList<CustomClass> 的元素,我发现有一种更新更好的显示列表的方法 - RecyclerView

我的问题是如何将其实现到我的应用程序中。 我发现我需要使用一个 Adapter,但我不太明白如何正确地实施整个过程。

如果您想知道,我指的是 this 我一直在阅读的文档示例。

编辑:

更新我的代码后,它说无法解析符号 setOnEntryClickListener:

public class voting extends Activity {


RecyclerView myList;
private ArrayList<Player> players; // Players


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_voting);

    Intent intent = this.getIntent();
    Bundle bundle = intent.getExtras();
    players = (ArrayList<Player>)bundle.getSerializable("PLAYERS");

    myList = (RecyclerView) findViewById(R.id.charactersList);
    myList.setLayoutManager(new LinearLayoutManager(this));
    CoursesAdapter adapter = new CoursesAdapter(players);
    myList.setAdapter(adapter);
}

// OR RecyclerView with a click listener

CoursesAdapter clickAdapter = new CoursesAdapter(players);
clickAdapter.setOnEntryClickListener(new CoursesAdapter.OnEntryClickListener() {
    @Override
    public void onEntryClick(View view, int position) {
        // stuff that will happen when a list item is clicked
    }
});
recyclerView.setAdapter(clickAdapter);
}

所以我以为我把 interface 放在了错误的地方(很有可能),事实上我已经把它放在适配器 class 中,在它的末尾,对吧在 onAttachedToRecyclerView() 方法之后:

    @Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}


private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}



}

这是一个工作示例,希望对您有所帮助:

public class BankListAdapter extends RecyclerView.Adapter<BankListAdapter.BankListViewHolder> {

    ArrayList<BankListModel> bankListModels;
    FragmentActivity activity;
    View selectBank;

    public BankListAdapter(ArrayList<BankListModel> bankListModels, FragmentActivity activity) {
        this.bankListModels=bankListModels;
        this.activity=activity;
    }


    @Override
    public BankListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View bankListLayout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bank_list, null);
        BankListViewHolder bankListViewHolder = new BankListViewHolder(bankListLayout);
        return bankListViewHolder;
    }

    @Override
    public void onBindViewHolder(BankListViewHolder holder, int position) {
        holder.bankName.setText(bankListModels.get(position).getBankName());

    }

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

    public class BankListViewHolder extends RecyclerView.ViewHolder {
        TextView bankName;

        public BankListViewHolder(View itemView) {
            super(itemView);
            bankName = (TextView) itemView.findViewById(R.id.tv_bankName);
            selectBank = itemView.findViewById(R.id.cv_selectBank);

        }
    }
}

我记得我第一次阅读有关 RecyclerViews 的内容时 - 我同意一开始可能有点混乱。希望这个解释能帮助您更好地理解它。


RecyclerView 基础知识

1。添加 RecyclerView

首先,您需要将 RecyclerView 添加到 XML 布局中。我假设你知道如何做到这一点。您还可以在 Java 代码中声明它:

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

2。创建 Adapter 并理解 ViewHolder

接下来,你需要为它创建一个Adapter。这是实现 RecyclerView.Adapter<YourAdapter.YourViewHolder> 的 class。我稍后会解释这意味着什么。

我相信查看 Adapter 的示例有助于了解其工作原理(例如 one I created 用于开源应用程序)。我还强烈建议查看我在 GitHub 上作为 Gist 示例制作的一组 Java 文件:

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

我将在本说明中引用上面 link 中的示例文件,以便您可以跟进。

您可以看到 Adapter class 包含一个内部 class,这是您的 ViewHolder。因此,它需要扩展 RecyclerView.ViewHolder.

在此 ViewHolder 中,您声明将用于 RecyclerView 中每个列表项的布局变量。在 ViewHolder 的构造函数中,您分配这些变量。我指的是这部分代码(我在下面给出我的例子):

ExampleViewHolder(View itemView) {
    super(itemView);
    text1 = (TextView) itemView.findViewById(R.id.text1);
    text2 = (TextView) itemView.findViewById(R.id.text2);
}

这就是您 ViewHolder 所需的全部内容(Adapter 中的内部 class)。

3。了解 Adapter

像大多数 Java 对象一样,您需要在 Adapter class 中有一个构造函数和一些私有变量。这是我的:

private ArrayList<CustomClass> mCustomObjects;

public ExampleAdapter(ArrayList<CustomClass> arrayList) {
    mCustomObjects = arrayList;
}

您需要将 ArrayList<CustomClass> 作为构造函数参数,以便您可以传递列表,以便 Adapter 可以使用它。

如果您查看 Adapter class 的其余部分,它包含一些从扩展的方法中覆盖的方法。让我们快速浏览一下这些是什么:

  • getItemCount() return 是您列表的大小。
  • onCreateViewHolder(...) 用于扩充列表项的布局。
  • onBindViewHolder(...) 配置列表项的布局(例如,将文本设置为 TextView

在大多数情况下,getItemCount() 只会 return 您的 ArrayList<CustomClass>size()

onCreateViewHolder(...) 方法通常也保持不变:

@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
    return new ExampleViewHolder(view);
}

您可以看到我正在膨胀我将用作列表项的布局 (android.R.layout.simple_list_item_2)。此布局内置于 Android,因此我不需要创建它 - 当然,您可以使用任何您想要的布局,然后修改您的 Adapter 以获得您可能正在使用的小部件。此方法的 return 类型将匹配您命名为 ViewHolder 内部 class.

的任何内容

现在,有趣的是 onBindViewHolder(...)。您可以在此处配置布局,因此完全取决于您想要做什么。这是您可以使用的模板:

@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
    CustomClass object = mCustomObjects.get(position);

    String firstText = object.getFirstText()
    String secondText = object.getSecondText()

    holder.text1.setText(firstText);
    holder.text2.setText(secondText);
}

基本上,您可以通过 holder.myWidget 访问 ViewHolder 变量(用于列表项布局中的小部件)。 holder 部分来自参数,也就是我们之前谈到的 ViewHolder,而 myWidget 将是来自该参数的 View 变量的名称。

在上面的例子中,object有一个getFirstText()方法,而ViewHolder包含一个TextViewtext1),所以我是设置文本。

还有一种方法 - onAttachedToRecyclerView(...)。您可以将其用于更复杂的事情,但在基本层面上,通常是这样的:

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

4。配置 RecyclerView

记得一开始,当我们声明并分配我们的 RecyclerView?:

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

现在我们要配置它。

您首先设置 "layout manager"。这决定了每个列表项在屏幕上的显示方式。常见的有LinearLayoutManagerGridLayoutManager。前者将您的列表项放入标准列表中(其实没什么特别的,但非常有用),后者将您的列表项组织成网格类型的布局。

在我们的示例中,我们将使用 LinearLayoutManager。要在 RecyclerView 上设置它,我们这样做:

recyclerView.setLayoutManager(new LinearLayoutManager(this));

就这些了。

接下来我们要做的就是将我们之前创建和自定义的 Adapter class 设置为您的 RecyclerView:

ExampleAdapter adapter = new ExampleAdapter(yourCustomArrayList);
recyclerView.setAdapter(adapter);

在上面,我假设你的 adapter 只有一个参数,但这取决于你之前如何配置它。

5。使用您的 RecyclerView

上面的步骤应该会给你一个工作 RecyclerView。如果你卡住了,你可以看看我是如何将一个添加到我的应用程序中的here

你也可以翻翻Google samples for the RecyclerView implementation.

我希望所有这些都能让您清楚了解 RecyclerView 的工作原理。


添加点击侦听器

您可能想要添加一个点击侦听器,这样您就不会将 RecyclerView 仅用于显示项目。

为此,您的内部 ViewHolder class 需要实施 View.OnClickListener。这是因为您将 OnClickListener 设置为 ViewHolder 构造函数的 itemView 参数。让我告诉你我的意思:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}

您唯一需要添加的其他内容是 Adapter 的自定义界面和 setter 方法:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}

那么您的新的支持点击的 Adapter 就完成了。

现在,让我们使用它...

ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
    @Override
    public void onEntryClick(View view, int position) {
        // stuff that will happen when a list item is clicked
    }
});
recyclerView.setAdapter(clickAdapter);

这基本上就是您设置普通 Adapter 的方式,除了您使用自己创建的 setter 方法来控制当用户单击特定列表项时您将执行的操作。


重申一下,您可以查看我在 GitHub:

上针对此 Gist 制作的一组示例

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07