来自Json的ExpandableList视图

时间:2018-05-24 06:38:02

标签: android android-recyclerview expandablelistview android-json

目前使用ExpandableListView处理Android中的RecyclerView。我做了几乎所有的事情,但不知怎的,我得到了NullpointerException,我无法理清。任何帮助将不胜感激。

我正在分享代码段和git链接

Used Library

Code I have tried

应用程序正在修补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);
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

看到此问题,您的列表似乎有一些空值 https://github.com/bignerdranch/expandable-recycler-view/issues/321

我运行了您的代码,并在列表中记录了您在列表中包含空值的列表

检查此方法

@Override
 public List<Alloted_kids> getChildList() {
       return null;
 }

此方法应该返回非null值,此方法只会导致问题

使用return Collections.emptyList();而不是返回null