简体   繁体   English

为什么我在此代码中得到 null object 参考?

[英]Why am I getting a null object reference in this code?

I am working on an app that uses fragments.我正在开发一个使用片段的应用程序。 One fragment will show a list of users, which is working well.一个片段将显示一个用户列表,它运行良好。 Another fragment will show a list of access grades.另一个片段将显示访问等级列表。 The access grade list is not working.访问等级列表不起作用。 The code for the access grade list is below:访问等级列表的代码如下:

/**
 * The fragment onCreateView Method
 *
 * @param inflater the layout inflater
 * @param container the container that will hold the fragment
 * @param savedInstanceState the saved instance state
 * @return View object container the fragment view
 */
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_grade_list, container, false);
    assert getArguments() != null;
    String coName = getArguments().getString("CoName");
    String apiUrl = getArguments().getString("ApiUrl");
    update = getArguments().getBoolean("update");
    remove = getArguments().getBoolean("remove");
    new ManagerAdminApi(apiUrl);
    RecyclerView gRecyclerView = view.findViewById(R.id.recyclerViewGradeList);
    LinearLayoutManager gLayoutManager = new LinearLayoutManager(this.getActivity());
    **gRecyclerView.setHasFixedSize(true);**
    gAdapter = new FragmentGradeList.GradeAdapter(gradeList);
    gRecyclerView.setLayoutManager(gLayoutManager);
    gRecyclerView.setAdapter(gAdapter);
    TextView tvTitle = view.findViewById(R.id.tvTitle);
    tvTitle.setText(getString(R.string.grade_list_title, coName));
    readGrades();
    return view;
}

This is virtually the same code I used for the user list, however I am getting this error in the logcat window of Android Studio:这与我用于用户列表的代码几乎相同,但是我在 Android Studio 的 logcat window 中收到此错误:

2020-07-15 06:42:08.670 8019-8019/com.phoenixhosman.phoenixdbmanagers E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.phoenixhosman.phoenixdbmanagers, PID: 8019
    java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setHasFixedSize(boolean)' on a null object reference
        at com.phoenixhosman.phoenixdbmanagers.FragmentGradeList.onCreateView(FragmentGradeList.java:68)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:310)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6714)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)

It is saying I have a null object reference on the line I have in bold type.这是说我在粗体字的行上有一个 null object 参考。 I have checked and rechecked my code and I can not find why is it null.我检查并重新检查了我的代码,但找不到为什么它是 null。 My entire fragment code file is here:我的整个片段代码文件在这里:

/*
    The Phoenix Hospitality Management System
    Database Manager App
    Grade List Fragment Code File
    Copyright (c) 2020 By Troy Marker Enterprises
    All Rights Under Copyright Reserved

    The code in this file was created for use with the Phoenix Hospitality Management System (PHMS).
    Use of this code outside the PHMS is strictly prohibited.
 */
package com.phoenixhosman.phoenixdbmanagers;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Grade List Fragment code file
 * @author Troy Marker
 * @version 1.0.0
 */
public class FragmentGradeList extends Fragment {
    private RecyclerView.Adapter gAdapter;
    static InterfaceDataPasser dataPasser;
    public static Boolean update;
    public static Boolean remove;
    private final ArrayList<ObjectGrade> gradeList = new ArrayList<>();

    public FragmentGradeList() {
    }

    /**
     * The fragment onCreateView Method
     *
     * @param inflater the layout inflater
     * @param container the container that will hold the fragment
     * @param savedInstanceState the saved instance state
     * @return View object container the fragment view
     */
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_grade_list, container, false);
        assert getArguments() != null;
        String coName = getArguments().getString("CoName");
        String apiUrl = getArguments().getString("ApiUrl");
        update = getArguments().getBoolean("update");
        remove = getArguments().getBoolean("remove");
        new ManagerAdminApi(apiUrl);
        RecyclerView gRecyclerView = view.findViewById(R.id.recyclerViewGradeList);
        LinearLayoutManager gLayoutManager = new LinearLayoutManager(this.getActivity());
        gRecyclerView.setHasFixedSize(true);
        gAdapter = new FragmentGradeList.GradeAdapter(gradeList);
        gRecyclerView.setLayoutManager(gLayoutManager);
        gRecyclerView.setAdapter(gAdapter);
        TextView tvTitle = view.findViewById(R.id.tvTitle);
        tvTitle.setText(getString(R.string.grade_list_title, coName));
        readGrades();
        return view;
    }

    /**
     * Method to read the Grade list from the database
     */
    public void readGrades() {
        gradeList.clear();
        Call<String> call = ManagerAdminApi.getInstance().getApi().grade();
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
                String body = response.body();
                try {
                    assert body != null;
                    JSONObject obj = new JSONObject(body);
                    if(obj.optString("success").equals("true")) {
                        JSONArray data = obj.getJSONArray("data");
                        for (int i = 0; i < data.length(); i++) {
                            JSONObject datum = data.getJSONObject(i);
                            gradeList.add(new ObjectGrade(
                                    datum.getInt("id"),
                                    datum.getString("grade")
                            ));
                        }
                        gAdapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(getContext(), obj.optString("message"), Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
            }
        });
    }

    /**
     * recyclerviewUserList display adapter
     */
    public static class GradeAdapter extends RecyclerView.Adapter<FragmentGradeList.GradeAdapter.GradeViewHolder> {
        final private List<ObjectGrade> mGradeList;

        static class GradeViewHolder extends RecyclerView.ViewHolder {
            final TextView tvId;
            final TextView tvGrade;
            GradeViewHolder(View gradeView) {
                super(gradeView);
                tvId = gradeView.findViewById(R.id.tvId);
                tvGrade = gradeView.findViewById(R.id.tvGrade);
            }
        }
        GradeAdapter(ArrayList<ObjectGrade> gradelist) {
            mGradeList = gradelist;
        }
        @NonNull
        @Override
        public FragmentGradeList.GradeAdapter.GradeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_grade_list_item, parent,false);
            return new FragmentGradeList.GradeAdapter.GradeViewHolder(v);
        }
        @Override
        public void onBindViewHolder(@NonNull final FragmentGradeList.GradeAdapter.GradeViewHolder holder, int position) {
            final ObjectGrade currentGrade = mGradeList.get(position);
            holder.tvId.setText(String.valueOf(currentGrade.getId()));
            if (update) {
                holder.tvId.setTextColor(Color.parseColor("#06F522"));
            }
            if (remove) {
                holder.tvId.setTextColor(Color.parseColor("#FF2579"));
            }
            holder.tvGrade.setText(currentGrade.getGrade());
            if (update) {
                holder.tvId.setOnClickListener(v -> dataPasser.onGradeUpdate(currentGrade.getId()));
            }
            if (remove) {
                holder.tvId.setOnClickListener(v -> dataPasser.onGradeRemove(currentGrade.getId()));
            }
        }
        @Override
        public int getItemCount() {
            return mGradeList.size();
        }
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        dataPasser = (InterfaceDataPasser) context;
    }


}

Please forgive any formatting error.请原谅任何格式错误。 Thank you for any help.感谢您的任何帮助。

As requested here is the code of my fragment layout file:这里要求的是我的片段布局文件的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="@string/grade_list_title"
        android:textSize="36sp" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal">
        <TextView
            android:layout_width="75dp"
            android:layout_height="wrap_content"
            android:background="@drawable/x_border_3"
            android:gravity="center_horizontal"
            android:text="@string/id"
            android:textAllCaps="true"
            android:textColor="@color/Phoenix_Black" />
        <TextView
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:background="@drawable/x_border_3"
            android:gravity="center"
            android:text="@string/grade_1"
            android:textAllCaps="true"
            android:textColor="@color/Phoenix_Black" />
    </LinearLayout>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewGradeList"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"/>
</LinearLayout>

Thanks谢谢

Mike M. That was the problem, I had two layouts, portrait and landscape. Mike M. 这就是问题所在,我有两种布局,纵向和横向。 I removed the landscape and it worked.我删除了景观,它起作用了。 Thank you.谢谢你。 Im just curious.我只是好奇。 I have the same thing in another fragment, and have two layouts, and that one works fine.我在另一个片段中有同样的东西,有两种布局,一个很好用。 Why not ins the second fragment?为什么不插入第二个片段?

I just found out what was wrong.我刚刚发现出了什么问题。 Apparently I needed the list item layout for the recycler view.显然我需要回收站视图的列表项布局。 After I added the second view, it worked fine.添加第二个视图后,它运行良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM