目前使用ExpandableListView
处理Android中的RecyclerView
。我做了几乎所有的事情,但不知怎的,我得到了NullpointerException
,我无法理清。任何帮助将不胜感激。
我正在分享代码段和git链接
应用程序正在修补apadter类中的这一行
public DriverScheduleExpandableAdapter(Context mContext, @NonNull
List<DriverSchedule.Schedules> parentList) {
super(parentList);//////**this is where the app is crashing**
mRecipeList = parentList;
mInflater = LayoutInflater.from(mContext);
}
错误来了:
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference
at com.bignerdranch.expandablerecyclerview.model.ExpandableWrapper.generateChildItemList(ExpandableWrapper.java:99)
at com.bignerdranch.expandablerecyclerview.model.ExpandableWrapper.<init>(ExpandableWrapper.java:33)
at com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter.generateParentWrapper(ExpandableRecyclerAdapter.java:1357)
at com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter.generateFlattenedParentChildList(ExpandableRecyclerAdapter.java:1326)
at com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter.<init>(ExpandableRecyclerAdapter.java:120)
at com.rtstl.expandablelistview.adapter.DriverScheduleExpandableAdapter.<init>(DriverScheduleExpandableAdapter.java:23)
at com.rtstl.expandablelistview.MainActivity.inflateadapter(MainActivity.java:50)
at com.rtstl.expandablelistview.MainActivity.initview(MainActivity.java:41)
at com.rtstl.expandablelistview.MainActivity.onCreate(MainActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6357)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2408)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2515)
at android.app.ActivityThread.access$1000(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1379)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5571)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)
MainActivity.java
package com.rtstl.expandablelistview;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rtstl.expandablelistview.adapter.DriverScheduleAdapter;
import com.rtstl.expandablelistview.adapter.DriverScheduleExpandableAdapter;
import com.rtstl.expandablelistview.databinding.ActivityMainBinding;
import com.rtstl.expandablelistview.model.DriverSchedule;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
Context mContext;
DriverSchedule list_driver;
DriverScheduleAdapter adapter;
DriverScheduleExpandableAdapter adapterExp;
Gson gson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext=this;
gson=new Gson();
initview();
}
private void initview() {
binding= DataBindingUtil.setContentView(this, R.layout.activity_main);
inflateadapter();
}
private void inflateadapter() {
////for reading file from raw folder otherwise it's not required
list_driver= gson.fromJson(readFileFromRawDirectory(R.raw.driverschedule), new TypeToken<DriverSchedule>(){}.getType());
////////////////////////////////////////
Toast.makeText(mContext,""+list_driver.getData().getSclist().size(),Toast.LENGTH_SHORT).show();
adapterExp = new DriverScheduleExpandableAdapter(mContext, list_driver.getData().getSclist());
binding.rvRecycle.setLayoutManager(new LinearLayoutManager(this));
binding.rvRecycle.setAdapter(adapter);
}
private String readFileFromRawDirectory(int resourceId){
InputStream iStream = this.getResources().openRawResource(resourceId);
ByteArrayOutputStream byteStream = null;
try {
byte[] buffer = new byte[iStream.available()];
iStream.read(buffer);
byteStream = new ByteArrayOutputStream();
byteStream.write(buffer);
byteStream.close();
iStream.close();
//inflateadapter();
} catch (IOException e) {
e.printStackTrace();
}
return byteStream.toString();
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_Recycle"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</layout>
适配器类
package com.rtstl.expandablelistview.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
import com.rtstl.expandablelistview.R;
import com.rtstl.expandablelistview.model.DriverSchedule;
import java.util.List;
public class DriverScheduleExpandableAdapter extends ExpandableRecyclerAdapter<DriverSchedule.Schedules, DriverSchedule.Alloted_kids, RouteViewHolder, KidViewHolder> {
private LayoutInflater mInflater;
private List<DriverSchedule.Schedules> mRecipeList;
private static final int PARENT_NORMAL = 1;
private static final int CHILD_NORMAL = 3;
public DriverScheduleExpandableAdapter(Context mContext, @NonNull List<DriverSchedule.Schedules> parentList) {
super(parentList);//////**this is where the app is crashing**
mRecipeList = parentList;
mInflater = LayoutInflater.from(mContext);
}
@NonNull
@Override
public RouteViewHolder onCreateParentViewHolder(@NonNull ViewGroup parentViewGroup, int viewType) {
View recipeView;
switch (viewType) {
default:
case PARENT_NORMAL:
recipeView = mInflater.inflate(R.layout.group_item, parentViewGroup, false);
break;
}
return new RouteViewHolder(recipeView);
}
@NonNull
@Override
public KidViewHolder onCreateChildViewHolder(@NonNull ViewGroup childViewGroup, int viewType) {
View ingredientView;
switch (viewType) {
default:
case CHILD_NORMAL:
ingredientView = mInflater.inflate(R.layout.child_item, childViewGroup, false);
break;
}
return new KidViewHolder(ingredientView);
}
@Override
public void onBindParentViewHolder(@NonNull RouteViewHolder parentViewHolder, int parentPosition, @NonNull DriverSchedule.Schedules parent) {
parentViewHolder.bind(parent);
}
@Override
public void onBindChildViewHolder(@NonNull KidViewHolder childViewHolder, int parentPosition, int childPosition, @NonNull DriverSchedule.Alloted_kids child) {
childViewHolder.bind(child);
}
@Override
public int getParentViewType(int parentPosition) {
return PARENT_NORMAL;
}
@Override
public int getChildViewType(int parentPosition, int childPosition) {
return CHILD_NORMAL;
}
@Override
public boolean isParentViewType(int viewType) {
return viewType == PARENT_NORMAL;
}
}
DriverSchedule.java
package com.rtstl.expandablelistview.model;
import android.databinding.BaseObservable;
import com.bignerdranch.expandablerecyclerview.model.Parent;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
/**
* Created by User1 on 09-03-2018.
*/
public class DriverSchedule extends BaseObservable {
@SerializedName("status")
@Expose
public String status;
@SerializedName("msg")
@Expose
public String msg;
@SerializedName("data")
@Expose
public Data data;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public class Data {
@SerializedName("schedules")
@Expose
List<Schedules> sclist;
@SerializedName("driver_details")
@Expose
Driver_details driver_details;
public List<Schedules> getSclist() {
return sclist;
}
public void setSclist(List<Schedules> sclist) {
this.sclist = sclist;
}
public Driver_details getDriver_details() {
return driver_details;
}
public void setDriver_details(Driver_details driver_details) {
this.driver_details = driver_details;
}
}
public class Schedules implements Parent<Alloted_kids> {
@SerializedName("is_active")
@Expose
public String is_active;
@SerializedName("route_details")
@Expose
public Route_details route_details;
@SerializedName("alloted_kids")
@Expose
public List<Alloted_kids> alloted_kids;
public String getIs_active() {
return is_active;
}
public void setIs_active(String is_active) {
this.is_active = is_active;
}
public Route_details getRoute_details() {
return route_details;
}
public void setRoute_details(Route_details route_details) {
this.route_details = route_details;
}
public List<Alloted_kids> getAlloted_kids() {
return alloted_kids;
}
public void setAlloted_kids(List<Alloted_kids> alloted_kids) {
this.alloted_kids = alloted_kids;
}
@Override
public List<Alloted_kids> getChildList() {
return null;
}
@Override
public boolean isInitiallyExpanded() {
return false;
}
}
public class Driver_details {
@SerializedName("driver_details")
@Expose
public Driver_details1 driver_details;
public Driver_details1 getDriver_details() {
return driver_details;
}
public void setDriver_details(Driver_details1 driver_details) {
this.driver_details = driver_details;
}
}
public class Route_details {
@SerializedName("ds_id")
@Expose
public String ds_id;
@SerializedName("kidpool_route_id")
@Expose
public String kidpool_route_id;
public String getDs_id() {
return ds_id;
}
public void setDs_id(String ds_id) {
this.ds_id = ds_id;
}
public String getKidpool_route_id() {
return kidpool_route_id;
}
public void setKidpool_route_id(String kidpool_route_id) {
this.kidpool_route_id = kidpool_route_id;
}
}
public class Alloted_kids {
@SerializedName("kid_name")
@Expose
public String kid_name;
@SerializedName("kid_image")
@Expose
public String kid_image;
public String getKid_name() {
return kid_name;
}
public void setKid_name(String kid_name) {
this.kid_name = kid_name;
}
public String getKid_image() {
return kid_image;
}
public void setKid_image(String kid_image) {
this.kid_image = kid_image;
}
}
public class Driver_details1 {
@SerializedName("driver_id")
@Expose
public String driver_id;
@SerializedName("driver_name")
@Expose
public String driver_name;
public String getDriver_id() {
return driver_id;
}
public void setDriver_id(String driver_id) {
this.driver_id = driver_id;
}
public String getDriver_name() {
return driver_name;
}
public void setDriver_name(String driver_name) {
this.driver_name = driver_name;
}
}
}
KidViewHolder.java
package com.rtstl.expandablelistview.adapter;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.TextView;
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
import com.rtstl.expandablelistview.R;
import com.rtstl.expandablelistview.model.DriverSchedule;
class KidViewHolder extends ChildViewHolder{
private TextView mIngredientTextView;
public KidViewHolder(@NonNull View itemView) {
super(itemView);
mIngredientTextView = (TextView) itemView.findViewById(R.id.tv_childname);
}
public void bind(@NonNull DriverSchedule.Alloted_kids ingredient) {
mIngredientTextView.setText(ingredient.getKid_name());
}
}
RouteViewHolder.java
package com.rtstl.expandablelistview.adapter;
import android.annotation.SuppressLint;
import android.os.Build;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import com.bignerdranch.expandablerecyclerview.ParentViewHolder;
import com.rtstl.expandablelistview.R;
import com.rtstl.expandablelistview.model.DriverSchedule;
class RouteViewHolder extends ParentViewHolder {
private static final float INITIAL_POSITION = 0.0f;
private static final float ROTATED_POSITION = 180f;
@NonNull
private final ImageView mArrowExpandImageView;
private TextView mRecipeTextView;
public RouteViewHolder(@NonNull View itemView) {
super(itemView);
mRecipeTextView = (TextView) itemView.findViewById(R.id.group_name);
mArrowExpandImageView = (ImageView) itemView.findViewById(R.id.iv_exp);
}
public void bind(@NonNull DriverSchedule.Schedules recipe) {
mRecipeTextView.setText(recipe.getRoute_details().getKidpool_route_id());
}
@SuppressLint("NewApi")
@Override
public void setExpanded(boolean expanded) {
super.setExpanded(expanded);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (expanded) {
mArrowExpandImageView.setRotation(ROTATED_POSITION);
} else {
mArrowExpandImageView.setRotation(INITIAL_POSITION);
}
}
}
@Override
public void onExpansionToggled(boolean expanded) {
super.onExpansionToggled(expanded);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
RotateAnimation rotateAnimation;
if (expanded) { // rotate clockwise
rotateAnimation = new RotateAnimation(ROTATED_POSITION,
INITIAL_POSITION,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
} else { // rotate counterclockwise
rotateAnimation = new RotateAnimation(-1 * ROTATED_POSITION,
INITIAL_POSITION,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
}
rotateAnimation.setDuration(200);
rotateAnimation.setFillAfter(true);
mArrowExpandImageView.startAnimation(rotateAnimation);
}
}
}
答案 0 :(得分:2)
看到此问题,您的列表似乎有一些空值 https://github.com/bignerdranch/expandable-recycler-view/issues/321
我运行了您的代码,并在列表中记录了您在列表中包含空值的列表
检查此方法
@Override
public List<Alloted_kids> getChildList() {
return null;
}
此方法应该返回非null值,此方法只会导致问题
使用return Collections.emptyList();而不是返回null