我需要添加一个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
放在了错误的地方(非常可能),事实上我把它放在Adapter类的最后,就在{{1}之后。方法:
onAttachedToRecyclerView()
答案 0 :(得分:23)
我记得当我第一次读到RecyclerView
时 - 我同意它起初可能有点令人困惑。希望这个解释能帮助你更好地理解它。
RecyclerView
首先,您需要将RecyclerView
添加到XML布局中。我假设你知道怎么做。您还可以在Java代码中声明它:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);
Adapter
并了解ViewHolder
接下来,您需要为其创建 Adapter
。这是一个实现RecyclerView.Adapter<YourAdapter.YourViewHolder>
的类。我将在一分钟内解释这意味着什么。
我认为查看Adapter
的示例有助于了解其工作原理(例如,one I created用于开源应用)。我还强烈建议查看我在GitHub上的Gist上的一组Java文件:
https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07
我将在此解释中引用上面链接中的示例文件,以便您可以继续。
您可以看到Adapter
类包含一个内部类,即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
中的内部课程)所需的全部内容。
Adapter
与大多数Java对象一样,您需要在Adapter
类中为构造函数提供一些私有变量。这是我的:
private ArrayList<CustomClass> mCustomObjects;
public ExampleAdapter(ArrayList<CustomClass> arrayList) {
mCustomObjects = arrayList;
}
您需要将ArrayList<CustomClass>
作为构造函数参数,以便传递列表,以便Adapter
可以使用它。
如果查看Adapter
类的其余部分,它会包含一些方法,它会覆盖它扩展的内容。让我们快速了解一下这些是什么:
getItemCount()
会返回列表的大小。onCreateViewHolder(...)
用于扩充列表项的布局。onBindViewHolder(...)
配置列表项的布局(例如,将文字设置为TextView
)对于大多数情况,getItemCount()
只会返回size()
的{{1}}。
ArrayList<CustomClass>
方法通常也保持不变:
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中,因此我不需要创建它 - 当然,您可以使用您希望的任何布局,然后修改您可能正在使用的小部件的android.R.layout.simple_list_item_2
。此方法的返回类型将匹配您命名为Adapter
内部类的任何内容。
现在,有趣的一点是ViewHolder
。您可以在此处配置布局,因此完全取决于您要执行的操作。这是您可以使用的模板:
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);
}
访问ViewHolder
变量(列表项目布局中的小部件)。 holder.myWidget
部分来自参数,这是我们之前讨论过的holder
,而ViewHolder
将是myWidget
变量的名称。
在上面的示例中,View
采用object
方法,getFirstText()
包含ViewHolder
(TextView
),因此我设置了文本。
还有一种方法 - text1
。您可以将它用于更复杂的事情,但在基本层面上,通常是:
onAttachedToRecyclerView(...)
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
当我们宣布并分配我们的RecyclerView
时,请记住:
RecyclerView
现在我们要配置它。
首先设置&#34;布局管理器&#34;。这决定了每个列表项在屏幕上的显示方式。常见的是RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);
和LinearLayoutManager
。前者将您的列表项放入标准列表(没有什么特别的,但它非常有用),后者将列表项组织成网格类型的布局。
在我们的示例中,我们将使用GridLayoutManager
。要在LinearLayoutManager
上进行设置,我们会这样做:
RecyclerView
这就是全部。
我们接下来要做的就是将我们创建的recyclerView.setLayoutManager(new LinearLayoutManager(this));
课程设置为您之前的Adapter
:
RecyclerView
在上文中,我假设您的ExampleAdapter adapter = new ExampleAdapter(yourCustomArrayList);
recyclerView.setAdapter(adapter);
只有一个参数,但这取决于您之前的配置方式。
adapter
上述步骤可为您提供合作RecyclerView
。如果您遇到困难,可以查看我在应用here中添加的方式。
您还可以查看Google samples for the RecyclerView
implementation。
我希望所有这些都能让您清楚了解RecyclerView
的工作原理。
您可能希望添加一个点击监听器,这样您就不会仅使用RecyclerView
来显示项目。
为此,您的内部RecyclerView
课程需要实施ViewHolder
。这是因为您会将View.OnClickListener
设置为OnClickListener
构造函数的itemView
参数。让我告诉你我的意思:
ViewHolder
您需要添加的唯一其他内容是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());
}
}
}
的自定义界面和setter方法:
Adapter
因此,您的新点击支持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);
的,除了您使用您创建的setter方法来控制用户点击特定列表项时您将执行的操作。
重申一下,你可以在GitHub上看一下我在Gist上做的一组例子:
https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07
答案 1 :(得分:2)
这是一个有效的例子,希望它能帮到你:
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);
}
}
}