在 Android 中以编程方式编辑 RecyclerView 项目
Edit RecyclerView item programatically in Android
所以我有这个应用程序,我必须在其中制作一个 RecyclerView
,其中包含可以是 deleted/edited e.t.c.
的项目列表
我遵循了 youtube 上的教程,并在另一个布局上制作了一个自定义 CardView
项目,并为该项目制作了一个自定义适配器。
事情是,根据项目的状态,我必须改变一些东西(例如背景颜色或文本颜色)。
当我在 RecyclerView
activity 中这样做时,即使我有 ID,我也会得到 NullPointerException
。
如何在调用 Retrofit 时编辑以编程方式生成的项目列表中的那些 TextViews
?
boolean isEnded;
if(!endedAt.equals("null"))
{
endedAt = endedAt.substring(endedAt.indexOf("T") + 1, endedAt.lastIndexOf(":"));
isEnded=true;
}
else
{
endedAt="ongoing";
isEnded=false;
}
item.timeDifference=createdAt+" - "+endedAt;
if(externalSystem.equals("null"))
{
item.externalSystem="";
}
else
{
item.externalSystem = externalSystem;
}
Log.i("attr",externalSystem);
items.add(item);
itemAdapter=new ItemAdapter(getApplicationContext(), items);
recyclerView.setAdapter(itemAdapter);
if(isEnded) {
error-> externalSystemView.setTextColor(Color.BLACK);
}
这个应用比较大,不过我想你可以从这段代码中得到启发。
这是错误:尝试在空对象引用上调用虚方法'void android.widget.TextView.setTextColor(int)'
public class ItemAdapter extends
RecyclerView.Adapter<ItemAdapter.ItemViewHolder>{
private Context context;
private ArrayList<Item> itemList;
public ItemAdapter(Context context, ArrayList<Item> itemList)
{
this.context=context;
this.itemList=itemList;
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.item_layout,parent,false);
ItemViewHolder itemViewHolder=new ItemViewHolder(view);
return itemViewHolder;
}
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Item item=itemList.get(position);
holder.timeDifference.setText(item.timeDifference);
holder.title.setText(item.title);
holder.timeCounter.setText(item.timeCounter);
holder.externalSystem.setText(item.externalSystem);
holder.type.setText(item.type);
holder.project.setText(item.project);
MY IDEA
"holder.timeDifference.setTextColor(Color.parseColor(item.color));"
}
@Override
public int getItemCount() {
if(itemList!=null)
return itemList.size();
else
return 0;
}
public static class ItemViewHolder extends RecyclerView.ViewHolder
{
public CardView cardViewItem;
public TextView title;
public TextView project;
public TextView externalSystem;
public TextView timeDifference;
public TextView timeCounter;
public TextView type;
public ItemViewHolder(View itemView)
{
super(itemView);
cardViewItem=(CardView)itemView.findViewById(R.id.card_view_item);
title=(TextView)itemView.findViewById(R.id.title);
project=(TextView)itemView.findViewById(R.id.project);
externalSystem=
(TextView)itemView.findViewById(R.id.external_system);
timeDifference=
(TextView)itemView.findViewById(R.id.time_difference);
timeCounter=(TextView)itemView.findViewById(R.id.time_counter);
type=(TextView)itemView.findViewById(R.id.type);
}
编辑:我想我找到了一种方法,但我不知道它是否是最好的方法
解决方案需要稍微改变一下您的 Item
class。
您的问题是您没有正确地将 boolean
触发器从 Activity
传递给 RecyclerView.Adapter
。例如。 isEndedBoolean
的值来了解项目处于什么状态。您对所有三个 class 的使用都有正确的想法。
我建议做的是在您的 Item
class 中创建一个构造函数,传递来自您的 Activity
的值以在您的适配器中使用。我觉得使用 getters
和 setters
比直接从代码中分配变量更容易。
那么让我们开始吧,
boolean isEnded;
if(!endedAt.equals("null")) {
endedAt = endedAt.substring(endedAt.indexOf("T") + 1, endedAt.lastIndexOf(":"));
isEnded=true;
} else {
endedAt="ongoing";
isEnded=false;
}
String timeDifference = createdAt+" - "+endedAt;
if(externalSystem.equals("null")) {
externalSystem="";
} else {
externalSystem = externalSystem;
}
Log.i("attr",externalSystem);
items.add(new ItemModel(isEnded, timeDifference, externalSystem);
itemAdapter=new ItemAdapter(this, items);
recyclerView.setAdapter(itemAdapter);
itemAdapter.notifyDataSetChanged();
您会注意到我如何为 RecyclerView
中的每一行变量添加一个新的 ItemModel
到数组,然后将该数组传递给 Adapter
。这样可以更轻松地了解哪些变量正在传递给模型,从而更容易了解 Adapter
.
内位置的相应行
ItemModel
class 的示例如下所示:
public class ItemModel {
// Getter and Setter model for recycler view items
private boolean isEnded;
private String timeDifference;
private String externalSystem;
//other variables, title etc etc
public ItemModel(boolean isEnded, String timeDifference, String externalSystem) {
this.isEnded = isEnded;
this.timeDifference = timeDifference;
this.externalSystem = externalSystem;
//only pass to the model if you can access it from code above otherwise to assign the variables statically like you have.
}
public boolean getIsEnded() {return isEnded;}
public String getTimeDifference() {return timeDifference;}
public String getExternalSystem() { return externalSystem; }
}
以上信息只是一个指南,供您创建更高效的模型框架来传递数据,而不是使用静态变量。
现在要解决您的问题,您需要检查 if (item.getIsEnded())
,然后更改与 if
条件对应的文本颜色。
RecyclerView.Adapter
onBindViewHolder
看起来像:
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
ItemModel item =itemList.get(position);
holder.timeDifference.setText(item.getTimeDifference());
holder.title.setText(item.title);
holder.timeCounter.setText(item.timeCounter);
holder.externalSystem.setText(item.getExternalSystem());
holder.type.setText(item.type);
holder.project.setText(item.project);
if (item.getIsEnded() {
holder.timeDifference.setTextColor(item.color);
} else {
holder.timeDifference.setTextColor(item.color);
}
}
Adapter
的目的是扩充布局,将组件绑定到该布局,并在专用位置对与布局对应的项目执行功能。您需要知道列表中的哪个项目处于哪个状态,仅靠 Activity
无法做到这一点。请注意 Adapter
在将 Activity
中的代码与 RecyclerView
.
的实际 activity 分开方面的作用。
所以我有这个应用程序,我必须在其中制作一个 RecyclerView
,其中包含可以是 deleted/edited e.t.c.
我遵循了 youtube 上的教程,并在另一个布局上制作了一个自定义 CardView
项目,并为该项目制作了一个自定义适配器。
事情是,根据项目的状态,我必须改变一些东西(例如背景颜色或文本颜色)。
当我在 RecyclerView
activity 中这样做时,即使我有 ID,我也会得到 NullPointerException
。
如何在调用 Retrofit 时编辑以编程方式生成的项目列表中的那些 TextViews
?
boolean isEnded;
if(!endedAt.equals("null"))
{
endedAt = endedAt.substring(endedAt.indexOf("T") + 1, endedAt.lastIndexOf(":"));
isEnded=true;
}
else
{
endedAt="ongoing";
isEnded=false;
}
item.timeDifference=createdAt+" - "+endedAt;
if(externalSystem.equals("null"))
{
item.externalSystem="";
}
else
{
item.externalSystem = externalSystem;
}
Log.i("attr",externalSystem);
items.add(item);
itemAdapter=new ItemAdapter(getApplicationContext(), items);
recyclerView.setAdapter(itemAdapter);
if(isEnded) {
error-> externalSystemView.setTextColor(Color.BLACK);
}
这个应用比较大,不过我想你可以从这段代码中得到启发。
这是错误:尝试在空对象引用上调用虚方法'void android.widget.TextView.setTextColor(int)'
public class ItemAdapter extends
RecyclerView.Adapter<ItemAdapter.ItemViewHolder>{
private Context context;
private ArrayList<Item> itemList;
public ItemAdapter(Context context, ArrayList<Item> itemList)
{
this.context=context;
this.itemList=itemList;
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.item_layout,parent,false);
ItemViewHolder itemViewHolder=new ItemViewHolder(view);
return itemViewHolder;
}
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Item item=itemList.get(position);
holder.timeDifference.setText(item.timeDifference);
holder.title.setText(item.title);
holder.timeCounter.setText(item.timeCounter);
holder.externalSystem.setText(item.externalSystem);
holder.type.setText(item.type);
holder.project.setText(item.project);
MY IDEA
"holder.timeDifference.setTextColor(Color.parseColor(item.color));"
}
@Override
public int getItemCount() {
if(itemList!=null)
return itemList.size();
else
return 0;
}
public static class ItemViewHolder extends RecyclerView.ViewHolder
{
public CardView cardViewItem;
public TextView title;
public TextView project;
public TextView externalSystem;
public TextView timeDifference;
public TextView timeCounter;
public TextView type;
public ItemViewHolder(View itemView)
{
super(itemView);
cardViewItem=(CardView)itemView.findViewById(R.id.card_view_item);
title=(TextView)itemView.findViewById(R.id.title);
project=(TextView)itemView.findViewById(R.id.project);
externalSystem=
(TextView)itemView.findViewById(R.id.external_system);
timeDifference=
(TextView)itemView.findViewById(R.id.time_difference);
timeCounter=(TextView)itemView.findViewById(R.id.time_counter);
type=(TextView)itemView.findViewById(R.id.type);
}
编辑:我想我找到了一种方法,但我不知道它是否是最好的方法
解决方案需要稍微改变一下您的 Item
class。
您的问题是您没有正确地将 boolean
触发器从 Activity
传递给 RecyclerView.Adapter
。例如。 isEndedBoolean
的值来了解项目处于什么状态。您对所有三个 class 的使用都有正确的想法。
我建议做的是在您的 Item
class 中创建一个构造函数,传递来自您的 Activity
的值以在您的适配器中使用。我觉得使用 getters
和 setters
比直接从代码中分配变量更容易。
那么让我们开始吧,
boolean isEnded;
if(!endedAt.equals("null")) {
endedAt = endedAt.substring(endedAt.indexOf("T") + 1, endedAt.lastIndexOf(":"));
isEnded=true;
} else {
endedAt="ongoing";
isEnded=false;
}
String timeDifference = createdAt+" - "+endedAt;
if(externalSystem.equals("null")) {
externalSystem="";
} else {
externalSystem = externalSystem;
}
Log.i("attr",externalSystem);
items.add(new ItemModel(isEnded, timeDifference, externalSystem);
itemAdapter=new ItemAdapter(this, items);
recyclerView.setAdapter(itemAdapter);
itemAdapter.notifyDataSetChanged();
您会注意到我如何为 RecyclerView
中的每一行变量添加一个新的 ItemModel
到数组,然后将该数组传递给 Adapter
。这样可以更轻松地了解哪些变量正在传递给模型,从而更容易了解 Adapter
.
ItemModel
class 的示例如下所示:
public class ItemModel {
// Getter and Setter model for recycler view items
private boolean isEnded;
private String timeDifference;
private String externalSystem;
//other variables, title etc etc
public ItemModel(boolean isEnded, String timeDifference, String externalSystem) {
this.isEnded = isEnded;
this.timeDifference = timeDifference;
this.externalSystem = externalSystem;
//only pass to the model if you can access it from code above otherwise to assign the variables statically like you have.
}
public boolean getIsEnded() {return isEnded;}
public String getTimeDifference() {return timeDifference;}
public String getExternalSystem() { return externalSystem; }
}
以上信息只是一个指南,供您创建更高效的模型框架来传递数据,而不是使用静态变量。
现在要解决您的问题,您需要检查 if (item.getIsEnded())
,然后更改与 if
条件对应的文本颜色。
RecyclerView.Adapter
onBindViewHolder
看起来像:
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
ItemModel item =itemList.get(position);
holder.timeDifference.setText(item.getTimeDifference());
holder.title.setText(item.title);
holder.timeCounter.setText(item.timeCounter);
holder.externalSystem.setText(item.getExternalSystem());
holder.type.setText(item.type);
holder.project.setText(item.project);
if (item.getIsEnded() {
holder.timeDifference.setTextColor(item.color);
} else {
holder.timeDifference.setTextColor(item.color);
}
}
Adapter
的目的是扩充布局,将组件绑定到该布局,并在专用位置对与布局对应的项目执行功能。您需要知道列表中的哪个项目处于哪个状态,仅靠 Activity
无法做到这一点。请注意 Adapter
在将 Activity
中的代码与 RecyclerView
.