android - RecyclerView 不能在 onBindViewHolder() 中使用 setText()
问题描述
在我的应用程序中,我尝试在recyclerView中使用两个布局,一切正常,直到我尝试应用程序并崩溃说:
尝试在空对象引用上调用虚拟方法 'void android.widget.TextView.setText(int)'。
错误在这一行,每次我尝试在第一个布局中设置文本时:
groupsViewHolder.fTeamName.setText(R.string.russia);
第二个布局工作正常,但第一个不是。
我想要的是解决错误,以及是否有比多次使用switch更好的方法。感谢您的帮助。
这是我的代码:
MatchesAdapter.java:
public class MatchesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final private ListItemClickListener mOnClickListener;
private Context context;
private int mNumberItems;
public MatchesAdapter(Context context, int numberOfItems, ListItemClickListener listener) {
mNumberItems = numberOfItems;
mOnClickListener = listener;
this.context = context;
}
@Override
public int getItemViewType(int position) {
return position;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
if (viewType >= 0 && viewType <= 47) {
int layoutIdForListItem = R.layout.matches_groups_item;
View view = inflater.inflate(layoutIdForListItem, viewGroup, false);
Log.e("QQ","Groups");
return new GroupsViewHolder(view);
} else {
int layoutIdForListItem = R.layout.matches_rounds_item;
View view = inflater.inflate(layoutIdForListItem, viewGroup, false);
Log.e("QQ","Rounds");
return new RoundsViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder mainHolder, int position) {
mainHolder;
String[] array = context.getResources().getStringArray(R.array.times);
final int itemType = getItemViewType(position);
if (itemType >= 0 && itemType <= 47) {
GroupsViewHolder groupsViewHolder = (GroupsViewHolder) mainHolder;
groupsViewHolder.bind(position);
switch (position) {
case 0:
groupsViewHolder.listItemDate.setText(array[position]);
groupsViewHolder.fTeamName.setText(R.string.russia);
groupsViewHolder.sTeamName.setText(R.string.saudi_arabia);
break;
case 1:
groupsViewHolder.listItemDate.setText(array[position]);
groupsViewHolder.fTeamName.setText(R.string.egypt);
groupsViewHolder.sTeamName.setText(R.string.uruguay);
break;
//.... many cases until case 47 then
} else {
RoundsViewHolder roundsViewHolder = (RoundsViewHolder) mainHolder;
roundsViewHolder.bind(position);
switch (position) {
case 48:
roundsViewHolder.listItemTitle.setText(R.string.round16);
roundsViewHolder.listItemDate.setText(array[position]);
roundsViewHolder.fTeamName.setText(R.string.group_a_winner);
roundsViewHolder.sTeamName.setText(R.string.group_b_runner_up);
break;
case 49:
roundsViewHolder.listItemTitle.setText(R.string.round16);
roundsViewHolder.listItemDate.setText(array[position]);
roundsViewHolder.fTeamName.setText(R.string.group_c_winner);
roundsViewHolder.sTeamName.setText(R.string.group_d_runner_up);
break;
// until the end of cases then
@Override
public int getItemCount() {
return mNumberItems;
}
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
class GroupsViewHolder extends RecyclerView.ViewHolder
implements OnClickListener {
TextView listItemDate, listItemMatchNumber, fTeamName, sTeamName;
View fTeamView;
View sTeamView;
public GroupsViewHolder(View itemView) {
super(itemView);
listItemDate = itemView.findViewById(R.id.match_date);
listItemMatchNumber = itemView.findViewById(R.id.match_number);
fTeamView = itemView.findViewById(R.id.groups_match_t1);
fTeamName = fTeamView.findViewById(R.id.match_team_name_for_groups);
sTeamView = itemView.findViewById(R.id.groups_match_t2);
sTeamName = sTeamView.findViewById(R.id.match_team_name_for_groups);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemMatchNumber.setText(String.valueOf(listIndex + 1));
}
@Override
public void onClick(View v) {
int clickedPosition = getAdapterPosition();
mOnClickListener.onListItemClick(clickedPosition);
}
}
class RoundsViewHolder extends RecyclerView.ViewHolder
implements OnClickListener {
TextView listItemTitle, listItemDate, listItemMatchNumber, fTeamName, sTeamName;
View fTeamView;
View sTeamView;
public RoundsViewHolder(View itemView) {
super(itemView);
listItemTitle = itemView.findViewById(R.id.round_card_title);
listItemDate = itemView.findViewById(R.id.round_match_date);
listItemMatchNumber = itemView.findViewById(R.id.round_match_number);
fTeamView = itemView.findViewById(R.id.round_match_t1);
fTeamName = fTeamView.findViewById(R.id.match_team_name);
sTeamView = itemView.findViewById(R.id.round_match_t2);
sTeamName = sTeamView.findViewById(R.id.match_team_name);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemMatchNumber.setText(String.valueOf(listIndex + 1));
}
@Override
public void onClick(View v) {
int clickedPosition = getAdapterPosition();
mOnClickListener.onListItemClick(clickedPosition);
}}}
match_groups_item.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/mathes_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/match_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:textColor="@color/red"
android:textSize="18sp" />
<TextView
android:id="@+id/match_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:text="@string/select_winner" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tv_informer"
android:layout_marginTop="45dp"
android:baselineAligned="false"
android:orientation="horizontal">
<include
android:id="@+id/groups_match_t1"
layout="@layout/team_no_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp" />
<include
android:id="@+id/groups_match_t2"
layout="@layout/team_no_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
team_no_button.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/match_team_name_for_groups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" />
match_rounds_items.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/mathes_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/round_card_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:textColor="@color/red"
android:textSize="18sp" />
<TextView
android:id="@+id/round_match_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:textColor="@color/red"
android:textSize="18sp" />
<TextView
android:id="@+id/round_match_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="@string/select_winner" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:baselineAligned="false"
android:orientation="horizontal">
<include
android:id="@+id/round_match_t1"
layout="@layout/team_no_buttons_shirts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:gravity="center_horizontal"
android:text="@string/vs" />
<include
android:id="@+id/round_match_t2"
layout="@layout/team_no_buttons_shirts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
team_no_buttons_shirts.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/match_team_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp" />
日志猫:
06-26 11:58:13.111 4407-4407/sy.aya.ayaworldcup2018 E/QQ: Groups
06-26 11:58:13.114 4407-4407/sy.aya.ayaworldcup2018 D/AndroidRuntime: Shutting down VM
06-26 11:58:13.128 4407-4407/sy.aya.ayaworldcup2018 E/AndroidRuntime: FATAL EXCEPTION: main
Process: sy.aya.ayaworldcup2018, PID: 4407
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference
at sy.aya.ayaworldcup2018.MatchesAdapter.onBindViewHolder(MatchesAdapter.java:72)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5647)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5913)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:443)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:761)
at android.view.View.layout(View.java:19679)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2511)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2227)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1407)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6783)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6499)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
06-26 11:58:13.129 4407-4407/sy.aya.ayaworldcup2018 E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:108)
解决方案
正如@Cheticamp 所说,groups_match_t1
您在 tag 中指定的 id ( )<include />
将覆盖 id ( match_team_name_for_groups
) 中的team_no_buttons.xml
,因此您只能找到具有 id 的视图groups_match_t1
,所以这一行:
fTeamView = itemView.findViewById(R.id.groups_match_t1);
会找到一个视图,它实际上是TextView
它本身,然后:
fTeamName = fTeamView.findViewById(R.id.match_team_name_for_groups);
将返回 null,因为fTeamView
. 所以你可以使用:
fTeamName = itemView.findViewById(R.id.groups_match_t1);
获取TextView
,然后删除fTeamView
.
并且因为team_no_buttons_shirts.xml
有一个额外LinearLayout
的,idmatch_team_name
不会被覆盖,所以:
fTeamView = itemView.findViewById(R.id.round_match_t1);
将返回LinearLayout
, 和
fTeamName = fTeamView.findViewById(R.id.match_team_name);
将找到正确的TextView
哪个是LinearLayout
.
此外,Tor Norbye写道:
标签不是真实的
<include>
视图,所以 findByView 不会找到它。@id 属性(以及您在包含标签上设置的任何其他属性)改为应用于包含布局的根标签。所以你的 activity.getView(R.id.included1) 实际上应该是<TextView>
它本身。
推荐阅读
- neo4j - 相关节点上的 Cypher 查询过滤器
- android - 如何使用 android 中的互联网连接检查手机检查服务器连接是否可用?
- c# - 使用 SQL Server Management Studio 时如何在 web.config 中添加连接字符串?
- xamarin.forms - 消息中心未从 xamarin ios 任务调用
- c++ - 如何在 QByteArray 中找到两个无符号字符
- python - 如何在 aws-glue 中使用 python 包
- rest - 为什么编码的“斜线”在restful api中不能按预期工作?
- java - Eclipse 文件未出现在提交中
- php - 仅将单击的按钮更改为新按钮
- apache-spark - 使用 Spark 覆盖 C 盘上的 csv 文件