Android:尝试在onBindViewHolder中的空对象引用上调用虚拟方法

时间:2019-05-07 03:10:22

标签: android-recyclerview recycler-adapter android-cardview

我的应用程序应该解析JSON数据并将其显示在回收者视图中。当我运行该应用程序时,它因以下错误而崩溃:enter image description here

我已经多次检查代码以确保我调用了正确的资源文件,但是仍然找不到问题的根源。日志猫告诉我问题出在回收者视图适配器类的onBindViewHolder方法中,但是一切对我来说都很正常。谁能指出我正确的方向?这是相关代码:

Recycler View适配器:

    public class IndRvAdapter extends RecyclerView.Adapter<IndRvAdapter.MyViewHolder> {

    private Context context;
    private List<Ind> indList;

    public IndRvAdapter(Context context, List<Ind> indList) {
        this.context = context;
        this.indList = indList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view;
        LayoutInflater inflater = LayoutInflater.from(context);
        view = inflater.inflate(R.layout.ind_card, viewGroup, false);
        final MyViewHolder viewHolder = new MyViewHolder(view);
        viewHolder.indView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(context, SingleInd.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                i.putExtra("pacshort", indList.get(viewHolder.getAdapterPosition()).getPacshort());
                i.putExtra("supopp", indList.get(viewHolder.getAdapterPosition()).getSuppopp());
                i.putExtra("candname", indList.get(viewHolder.getAdapterPosition()).getCandname());
                i.putExtra("district", indList.get(viewHolder.getAdapterPosition()).getDistrict());
                i.putExtra("amount", indList.get(viewHolder.getAdapterPosition()).getAmount());
                i.putExtra("party", indList.get(viewHolder.getAdapterPosition()).getExpParty());
                i.putExtra("payee", indList.get(viewHolder.getAdapterPosition()).getPayee());
                i.putExtra("date", indList.get(viewHolder.getAdapterPosition()).getDate());
                i.putExtra("origin", indList.get(viewHolder.getAdapterPosition()).getOrigin());
                i.putExtra("source", indList.get(viewHolder.getAdapterPosition()).getSource());
                context.startActivity(i);
            }
        });
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        myViewHolder.pacshorts.setText(indList.get(i).getPacshort());
        myViewHolder.supOpp.setText(indList.get(i).getSuppopp());
        myViewHolder.candName.setText(indList.get(i).getCandname());
        myViewHolder.district.setText(indList.get(i).getDistrict());
    }

    @Override
    public int getItemCount() {
        return indList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder{
        TextView pacshorts, supOpp, candName, district;
        LinearLayout indView;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            pacshorts = itemView.findViewById(R.id.tv_pacshort);
            supOpp = itemView.findViewById(R.id.tv_suppopp);
            candName = itemView.findViewById(R.id.tv_candname);
            district = itemView.findViewById(R.id.tv_district);
            indView = itemView.findViewById(R.id.ind_view);
        }
    }
}

卡片查看资源:

<?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"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@+id/ind_view">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:elevation="3dp"
        card_view:cardCornerRadius="15dp"
        card_view:cardElevation="4dp"
        card_view:cardUseCompatPadding="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorPrimaryDark">

            <TextView
                android:id="@+id/pacshort"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="TextView" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/pacshort"
                android:id="@+id/tv_suppop"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/tv_candname"
                android:layout_below="@+id/tv_suppop"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/tv_district"
                android:layout_below="@+id/tv_candname"/>
        </RelativeLayout>
    </android.support.v7.widget.CardView>


</LinearLayout>

回收者视图:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/background_color"
    tools:context=".IndExpend">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/ind_rv">
    </android.support.v7.widget.RecyclerView>

</RelativeLayout>

解析JSON数据的主要活动

    public class IndExpend extends AppCompatActivity {
    /*
    * Open secrets API: Returns the 50 latest independent expenditures transactions
    * Updated every 4 days
    */

    private static final String url = "http://www.opensecrets.org/api/?method=independentExpend&output=json&apikey=d1ff8f708ca0745d75e9ffa0ee6f3d09";
    private LinearLayoutManager linearLayoutManager;
    private List <Ind> indList;
    private RecyclerView myrv;
    private RecyclerView.Adapter adapter;

    public IndExpend(){}

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ind_expend);

        linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

        myrv = findViewById(R.id.ind_rv);
        indList = new ArrayList<>();
        adapter = new IndRvAdapter(this, indList);

        myrv.setHasFixedSize(true);
        myrv.setLayoutManager(linearLayoutManager);
        myrv.setAdapter(adapter);

        getData();
    }

    private void getData() {
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progressDialog.dismiss();
                try {
                    JSONObject object = new JSONObject (response);
                    JSONObject responseObj = object.getJSONObject("response");
                    JSONArray array = responseObj.getJSONArray("indexp");
                    for (int i = 0; i < array.length(); i++){
                        JSONObject attributesObj = array.getJSONObject(i).getJSONObject("@attributes");
                        Ind ind = new Ind(attributesObj.getString("pacshort"),
                                attributesObj.getString("suppopp"),
                                attributesObj.getString("candname"),
                                attributesObj.getString("district"),
                                attributesObj.getString("amount"),
                                attributesObj.getString("party"),
                                attributesObj.getString("payee"),
                                attributesObj.getString("date"),
                                attributesObj.getString("origin"),
                                attributesObj.getString("source"));
                        indList.add(ind);
                    }
                    adapter = new IndRvAdapter(getApplicationContext(), indList);
                    myrv.setAdapter(adapter);
                }catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("Volley", error.toString());
                progressDialog.dismiss();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this );
        requestQueue.add(stringRequest);
    }
}

有人可以帮助我找到问题的根源吗?

1 个答案:

答案 0 :(得分:0)

我认为这是因为您正在尝试使用此ID绑定视图:

pacshorts = itemView.findViewById(R.id.tv_pacshort);

但是在布局文件中,该元素的ID只是pacshort:

<TextView
            android:id="@+id/pacshort"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="TextView" />

通常,由于两种原因之一,在Android上工作时会发生这些类型的空指针异常。首先,正在膨胀的res文件不正确,其次,用于绑定视图的ID拼写错误或该视图中不存在。

相关问题