gpt4 book ai didi

java - ListView 显示不同类型的行

转载 作者:行者123 更新时间:2023-12-02 02:03:01 26 4
gpt4 key购买 nike

我有一个 ListView 和一个 BaseAdapter。在适配器中我展示了 7 种不同类型的 View 。

此图像显示当我运行项目时,所有 ListView 和内部 View 都正确加载。但是当我向下滚动 ListView 时,出现错误。 Show all good

当我运行项目时,所有内容都显示良好,但是当我向下滚动 ListView 时出现问题,并向我抛出错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.panelapps.mapen, PID: 25969
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.panelapps.uiformcreator.UIFormAdapter.getView(UIFormAdapter.java:234)
at android.widget.AbsListView.obtainView(AbsListView.java:2413)
at android.widget.ListView.makeAndAddView(ListView.java:1975)
at android.widget.ListView.fillDown(ListView.java:709)
at android.widget.ListView.fillGap(ListView.java:673)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5475)
at android.widget.ListView.trackMotionScroll(ListView.java:1894)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3708)
at android.widget.AbsListView.onTouchMove(AbsListView.java:4157)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3964)
at android.view.View.dispatchTouchEvent(View.java:9957)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2705)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2386)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2711)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2400)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:416)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1834)
at android.app.Activity.dispatchTouchEvent(Activity.java:3154)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:378)
at android.view.View.dispatchPointerEvent(View.java:10177)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4650)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4518)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3969)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4022)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3988)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3996)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3969)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4022)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3988)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4117)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3996)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3969)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4022)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3988)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3996)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3969)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6459)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6433)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6394)
E/AndroidRuntime: at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6593)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6541)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6616)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:613)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)

我的 BaseAdapter 代码是:

public class UIFormAdapter extends BaseAdapter {
CallbackFormAdapter callback;

public interface CallbackFormAdapter {
void getData();
}

Context context;
ArrayList<Form> UIForm = new ArrayList<>();
private LayoutInflater inflater;

//functino
Function function = new Function();

public UIFormAdapter(Context context, ArrayList<Section> form, CallbackFormAdapter callback) {
this.context = context;
this.callback = callback;

//do the form
for (int i = 0; i<form.size(); i++){
//add the separator
UIForm.add(new Form("", form.get(i).getText(), 0));

//go over the forms inside
for (int j = 0; j<form.get(i).getForms().size(); j++){
UIForm.add(form.get(i).getForms().get(j));
}
}
}

@Override
public int getCount() {
return UIForm.size();
}

@Override
public Object getItem(int position) {
return UIForm.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public int getItemViewType(int position) {
return UIForm.get(position).getType();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
//holder
Holder viewHolder = null;

//get the data
Form data = UIForm.get(position);

//if inflater inicialize
if (inflater == null)
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

if (convertView == null){
//get the tipe
int type = getItemViewType(position);

//switch type
switch (type){
case 0:
convertView = inflater.inflate(R.layout.separator, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.txtSection.setText(data.getText());
break;
case Types.EditText:
convertView = inflater.inflate(R.layout.text_edit, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.etEditText.setHint(data.getText());
break;
case Types.Single_Spinner:
convertView = inflater.inflate(R.layout.single_spinner, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.txtSingleSpinner.setText(data.getText());
break;
case Types.Spinner:
convertView = inflater.inflate(R.layout.spinner, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.spinner.setAdapter(data.getAdapter());
viewHolder.spinner.setBackgroundColor(Color.LTGRAY);
break;
case Types.Date:
convertView = inflater.inflate(R.layout.button, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.button.setText(data.getText());
viewHolder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar mcurrentDate = Calendar.getInstance();
final int[] mYear = {mcurrentDate.get(Calendar.YEAR)};
final int[] mMonth = {mcurrentDate.get(Calendar.MONTH)};
final int[] mDay = {mcurrentDate.get(Calendar.DAY_OF_MONTH)};

DatePickerDialog mDatePicker = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker datepicker, int selectedyear, int selectedmonth, int selectedday) {
Calendar myCalendar = Calendar.getInstance();
myCalendar.set(Calendar.YEAR, selectedyear);
myCalendar.set(Calendar.MONTH, selectedmonth);
myCalendar.set(Calendar.DAY_OF_MONTH, selectedday);

//date
String myDate = function.dateToString(myCalendar.getTime(), "dd/MM/yyyy");
//viewHolder.button.setText(myDate);

mDay[0] = selectedday;
mMonth[0] = selectedmonth;
mYear[0] = selectedyear;
}
}, mYear[0], mMonth[0], mDay[0]);
//mDatePicker.setTitle("Select date");
mDatePicker.show();
}
});
break;
case Types.Button:
convertView = inflater.inflate(R.layout.button, parent, false);
//set the holder
viewHolder = new Holder(convertView, type);

viewHolder.button.setText(data.getText());
viewHolder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.getData();
}
});
break;
}

//set the holder
convertView.setTag(viewHolder);

}else{ //else customview null

//get the viewHolder
viewHolder = (Holder)convertView.getTag();

//get the tipe
int type = UIForm.get(position).getType();

switch (type){
case 0:
viewHolder.txtSection.setText(data.getText());
break;
case Types.EditText:
viewHolder.etEditText.setHint(data.getText());
break;
case Types.Single_Spinner:
viewHolder.txtSingleSpinner.setText(data.getText());
break;
case Types.Spinner:
viewHolder.spinner.setAdapter(data.getAdapter());
viewHolder.spinner.setBackgroundColor(Color.LTGRAY);
break;
case Types.Date:
viewHolder.button.setText(data.getText());
viewHolder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar mcurrentDate = Calendar.getInstance();
final int[] mYear = {mcurrentDate.get(Calendar.YEAR)};
final int[] mMonth = {mcurrentDate.get(Calendar.MONTH)};
final int[] mDay = {mcurrentDate.get(Calendar.DAY_OF_MONTH)};

DatePickerDialog mDatePicker = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker datepicker, int selectedyear, int selectedmonth, int selectedday) {
Calendar myCalendar = Calendar.getInstance();
myCalendar.set(Calendar.YEAR, selectedyear);
myCalendar.set(Calendar.MONTH, selectedmonth);
myCalendar.set(Calendar.DAY_OF_MONTH, selectedday);

//date
String myDate = function.dateToString(myCalendar.getTime(), "dd/MM/yyyy");
//viewHolder.button.setText(myDate);

mDay[0] = selectedday;
mMonth[0] = selectedmonth;
mYear[0] = selectedyear;
}
}, mYear[0], mMonth[0], mDay[0]);
//mDatePicker.setTitle("Select date");
mDatePicker.show();
}
});
break;
case Types.Button:
viewHolder.button.setText(data.getText());
viewHolder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.getData();
}
});
break;
}
}

//return the view
return convertView;
}

//CREATE THE HOLDERS
private class Holder{
EditText etEditText;
TextView txtSection;
MaterialSpinner spinner;
TextView txtSingleSpinner;
Button button;
public Holder(View v, int type) {
switch (type){
case Types.EditText:
this.etEditText = v.findViewById(R.id.etEditText);
break;
case Types.Single_Spinner:
this.txtSingleSpinner = v.findViewById(R.id.txtSingleSpinner);
break;
case 0:
this.txtSection = v.findViewById(R.id.txtSeparator);
break;
case Types.Spinner:
this.spinner = v.findViewById(R.id.spinner);
break;
case Types.Button:
this.button = v.findViewById(R.id.button);
break;
case Types.Date:
this.button = v.findViewById(R.id.button);
break;
}

}
}
}

错误显示我在下一行(viewHolder.button.setText ...):

case Types.Button:
viewHolder.button.setText(data.getText());

此按钮是 ListView 中显示的下一个按钮。

最佳答案

您需要重写getViewTypeCount来指示不同类型 View 的数量,否则当它尝试重用 View 时,它可能是不同的类型(因此convertView不为 null,但 ViewHolder 类型错误)。它适用于 View 的第一个屏幕,因为 convertView 对于所有 View 都将为 null。

@Override
public int getViewTypeCount() {
return 6; // question says 7 view types but I counted 6
}

参见here了解更多详细信息。

关于java - ListView 显示不同类型的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51274941/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com