我最近一直在做一个项目,我遇到了一个很奇怪的错误,我可以在许多设备上复制它。问题是ListView中的问题适用于前10-20个项目(总项目数为24),但之后如果我向下滚动则抛出异常。你认为这是一个Android问题,我应该切换到recyclerView吗?这是我的活动代码:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
ArrayList<Item> listViewArrayList;
ListView itemlistView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId("DAaBpKeoV0llJaxlHJGDP0cR6nkSWa5lV0qADN3R")
.clientKey("LAm9wqXDaLoHnhXzGe6uXmzJGkcIuAnuZDSXRDwW")
.server("https://parseapi.back4app.com")
.build()
);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
JSONArray jsonArray = new JSONArray();
for (Item item : listViewArrayList) {
jsonArray.put(item.toJsonObject());
}
Log.i("tag", jsonArray.toString());
Intent intent = new Intent(MainActivity.this, OrderSendActivity.class);
intent.putExtra("orderJson", jsonArray.toString());
startActivity(intent);
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
listViewArrayList = new ArrayList<>();
navigationView.setNavigationItemSelectedListener(this);
ParseQuery<ParseObject> menuQuery = ParseQuery.getQuery("Menu");
menuQuery.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_LONG).show();
for (ParseObject item : objects) {
listViewArrayList.add(new Item(item.getString("name"), item.getString("pricestring"), item.getInt("pricenumber")));
}
Log.i("debug", listViewArrayList.toString());
ItemAdapter adapter = new ItemAdapter(MainActivity.this, R.layout.layout, listViewArrayList);
Log.i("debug", adapter.toString());
itemlistView = findViewById(R.id.listView);
itemlistView.setAdapter(adapter);
} else {
Toast.makeText(MainActivity.this, "Download Failed", Toast.LENGTH_LONG).show();
}
}
});
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_first_layout) {
} else if (id == R.id.nav_second_layout) {
} else if (id == R.id.nav_third_layout) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private static class ViewHolder {
private TextView nameTextView;
private TextView priceTextView;
private Button plusButton;
private Button minusButton;
private TextView numberTextView;
}
private class ItemAdapter extends ArrayAdapter {
private ArrayList<Item> itemModelList;
private int resource;
ItemAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull ArrayList<Item> objects) {
super(context, resource, objects);
itemModelList = objects;
this.resource = resource;
}
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.nameTextView = convertView.findViewById(R.id.nameTextView);
holder.priceTextView = convertView.findViewById(R.id.priceTextView);
holder.plusButton = convertView.findViewById(R.id.plusButton);
holder.minusButton = convertView.findViewById(R.id.minusButton);
}
holder.numberTextView = convertView.findViewById(R.id.numberTextView);
holder.nameTextView.setText(itemModelList.get(position).getName());
holder.priceTextView.setText(itemModelList.get(position).getPrice());
holder.numberTextView.setText("0");
holder.plusButton.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SetTextI18n")
@Override
public void onClick(View view) {
itemModelList.get(position).incrementOrderNo();
holder.numberTextView.setText(Integer.toString(itemModelList.get(position).getOrderNo()));
}
});
holder.minusButton.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SetTextI18n")
@Override
public void onClick(View view) {
itemModelList.get(position).decrementOrderNo();
holder.numberTextView.setText(Integer.toString(itemModelList.get(position).getOrderNo()));
}
});
return convertView;
}
}
}
我的布局代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="88dp"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingStart="?listPreferredItemPaddingLeft"
android:paddingEnd="?listPreferredItemPaddingRight">
<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Masala Dosa"
android:textSize="16sp"
android:textColor="@color/black"/>
<TextView
android:id="@+id/priceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$15/ltr"
android:layout_below="@id/nameTextView"
android:textSize="14sp"/>
<Button
android:id="@+id/plusButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/priceTextView"
android:text="+"
android:textSize="14sp" />
<Button
android:id="@+id/minusButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="@+id/priceTextView"
android:text="-"
android:textSize="14sp" />
<TextView
android:id="@+id/numberTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/minusButton"
android:layout_alignBottom="@+id/minusButton"
android:layout_toEndOf="@+id/plusButton"
android:layout_toStartOf="@+id/minusButton"
android:text="0"
android:textAlignment="center"
android:textSize="14sp" />
</RelativeLayout>
最后,错误:
java.lang.NullPointerException: Attempt to write to field 'android.widget.TextView com.ranjusrecipebox.nalapaka.MainActivity$ViewHolder.numberTextView' on a null object reference
at com.ranjusrecipebox.nalapaka.MainActivity$ViewHolder.access$502(MainActivity.java:158)
at com.ranjusrecipebox.nalapaka.MainActivity$ItemAdapter.getView(MainActivity.java:195)
at android.widget.AbsListView.obtainView(AbsListView.java:2363)
at android.widget.ListView.makeAndAddView(ListView.java:1970)
at android.widget.ListView.fillDown(ListView.java:704)
at android.widget.ListView.fillGap(ListView.java:668)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5186)
at android.widget.ListView.trackMotionScroll(ListView.java:1889)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3568)
at android.widget.AbsListView.onTouchMove(AbsListView.java:3977)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3802)
at android.view.View.dispatchTouchEvent(View.java:10023)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2626)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2307)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2632)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2321)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:413)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1808)
at android.app.Activity.dispatchTouchEvent(Activity.java:3061)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:375)
at android.view.View.dispatchPointerEvent(View.java:10243)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4438)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4306)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3999)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4056)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)
02-19 21:24:39.687 7299-7299/com.ranjusrecipebox.nalapaka E/AndroidRuntime: at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6246)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6220)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6181)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6349)
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:6320)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6372)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:615)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
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:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
答案 0 :(得分:1)
您正面临此异常,因为您没有设置标记,但是当liistview滚动时您正在检索持有者,因此它在此行返回null
int numbers[14]
在创建像这样的视图持有者对象后设置标记
holder = (ViewHolder) convertView.getTag():
答案 1 :(得分:0)
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.nameTextView = convertView.findViewById(R.id.nameTextView);
holder.priceTextView = convertView.findViewById(R.id.priceTextView);
holder.plusButton = convertView.findViewById(R.id.plusButton);
holder.minusButton = convertView.findViewById(R.id.minusButton);
holder.numberTextView = convertView.findViewById(R.id.numberTextView);
convertView.setTag(holder);
}
尝试这样做。