问题描述
我想在Android设备上创建文件管理器,并在文件管理器中为ListView的内部类创建了一个自定义适配器。
xtabs(amountMean ~ week + state,sumTable)
# state
# week AL CA
# 1 2.500000 2.500000
# 2 2.666667 2.250000
以下是ListView中适配器的布局文件。
# Name of the resource we're selectively copying
GOOGLESERVICE_INFO_LOCATION=${PROJECT_DIR}/${TARGET_NAME}/App/Scripts/GoogleService-Info.plist
# Upload sysmbol
echo "Uploading dsym file"
"${PODS_ROOT}/FirebaseCrashlytics/upload-symbols" -gsp ${GOOGLESERVICE_INFO_LOCATION} -p ios ${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}
private static final class FileAdaptor extends BaseAdapter {
// These variables below would be set in my activity class
private final List<String> data = new ArrayList<>(); // file name
private final List<Drawable> data1 = new ArrayList<>(); // file icon
private final List<String> data2 = new ArrayList<>(); // file modified data
private final AppCompatActivity activity;
public FileAdaptor(final AppCompatActivity activity) {
this.activity = activity;
}
@Override
public final int getCount() {
return data.size();
}
@Override
public final Object getItem(final int position) {
return data.get(position);
}
public final void setData(final List<String> data) {
if (data != null) {
this.data.clear();
if (data.size() > 0)
this.data.addAll(data);
notifyDataSetChanged();
}
}
public final void setData1(final List<Drawable> data) {
if (data != null) {
this.data1.clear();
if (data.size() > 0)
this.data1.addAll(data);
notifyDataSetChanged();
}
}
public final void setData2(final List<String> data) {
if (data != null) {
this.data2.clear();
if (data.size() > 0)
this.data2.addAll(data);
notifyDataSetChanged();
}
}
public final String getData(final int position) {
return data.get(position);
}
public final Drawable getData1(final int position) {
return data1.get(position);
}
public final String getData2(final int position) {
return data2.get(position);
}
@Override
public final long getItemId(final int position) {
return 0;
}
@Override
public final View getView(final int position,final View convertView,final ViewGroup parent) {
View v;
if (convertView == null) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.file_manager_items,parent,false);
} else v = convertView;
ViewHolder h = (ViewHolder) v.getTag();
if (h == null) {
h = new ViewHolder(Objects.requireNonNull(activity.findViewById(R.id.itemIcon)),Objects.requireNonNull(activity.findViewById(R.id.fileName)),Objects.requireNonNull(activity.findViewById(R.id.fileInfo)));
v.setTag(h);
}
/**********************
**Error occurred here**
**********************/
h.fileIcon.setimageDrawable(getData1(position));
h.fileName.setText(getData(position).substring(getData(position).lastIndexOf("/")));
h.fileInfo.setText(getData2(position));
return v;
}
private static final class ViewHolder {
public final AppCompatimageView fileIcon;
public final AppCompatTextView fileName;
public final AppCompatTextView fileInfo;
public ViewHolder(@NonNull final AppCompatimageView fileIcon,@NonNull final AppCompatTextView fileName,@NonNull final AppCompatTextView fileInfo) {
this.fileIcon = fileIcon;
this.fileName = fileName;
this.fileInfo = fileInfo;
}
}
@NonNull
@Override
public final String toString() {
return "FileAdaptor{" +
"data=" + data +
",activity=" + activity +
'}';
}
}
看起来目前一切正常。但是,当我尝试在适配器的getView方法中为文本视图调用setText时,应用程序崩溃了,输出为java.lang.NullPointerException,但在此之前我已经叫过findViewById。
后来,我为ViewHold中的对象标注了NonNull,为findViewById标注了Objects.requireNonNull,但是仍然发生错误,错误输出如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatimageView
android:id="@+id/itemIcon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_weight="1"
android:gravity="center" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|start"
android:layout_weight="10"
android:gravity="start"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/fileName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/contents_title"
android:textSize="18sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/fileInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/contents" />
</LinearLayout>
</LinearLayout>
谁能帮助我解决这个问题
解决方法
您的代码应该是这样的,因为视图是适配器布局的一部分,而不是活动布局的一部分。
h = new ViewHolder(Objects.requireNonNull(v.findViewById(R.id.itemIcon)),Objects.requireNonNull(v.findViewById(R.id.fileName)),Objects.requireNonNull(v.findViewById(R.id.fileInfo)));
,
替换此:
h = new ViewHolder(Objects.requireNonNull(activity.findViewById(R.id.itemIcon)),Objects.requireNonNull(activity.findViewById(R.id.fileName)),Objects.requireNonNull(activity.findViewById(R.id.fileInfo)));
收件人:
h = new ViewHolder(Objects.requireNonNull(v.findViewById(R.id.itemIcon)),Objects.requireNonNull(v.findViewById(R.id.fileInfo)));
因为您必须在项目视图中找到子项目
, findViewById
可以返回Nullable
对象,因此不会使您脱离NPE。
您之所以会获得NPE,是因为您尝试通过活动布局中的findViewById
来扩大视图,并且它们实际上位于由convertView
表示的项目布局中。
因此,如下更改activity
与converView
h = new ViewHolder(Objects.requireNonNull(converView.findViewById(R.id.itemIcon)),Objects.requireNonNull(converView.findViewById(R.id.fileName)),Objects.requireNonNull(converView.findViewById(R.id.fileInfo)));