java - Recyclerview 适配器中的空指针异常

标签 java android android-adapter android-recyclerview

我一直在尝试为我的 Activity 实现回收 View ,但我一直收到 NullPointerException。这是我第一次制作 recyclerview,所以如果我做错了什么,请告诉我。我会告诉你我所有的代码,然后告诉你错误在哪里

我的主要 xml 布局(称为 activity_main.xml)

<android.support.v4.widget.DrawerLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:card_view="http://schemas.android.com/apk/res-auto"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/drawer"
                android:fitsSystemWindows="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/tool_bar"
            layout="@layout/tool_bar">
        </include>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/main_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingRight="8dp"
            android:paddingLeft="8dp"
            android:paddingTop="8dp"/>

    </LinearLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>

</android.support.v4.widget.DrawerLayout>

我的 recyclerview 行 xml(称为 main_recycler_view_row.xml)

<?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="match_parent">

    <android.support.v7.widget.CardView
        android:id="@+id/main_card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/period_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:textColor="@android:color/black"
                android:paddingTop="24dp"
                android:paddingLeft="16dp"
                android:paddingBottom="4dp"/>

            <TextView
                android:id="@+id/period_subtitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:paddingLeft="16dp"
                android:paddingBottom="16dp"/>

        </LinearLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>

我的主要 Activity

package maxbleggi.afstudentplanner;

import android.content.Intent;
import android.content.res.Configuration;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity
{
    // "MACROS" for user's class periods
    private final int PERIOD1 = 0;
    private final int PERIOD2 = 1;
    private final int PERIOD3 = 2;
    private final int PERIOD4 = 3;
    private final int PERIOD5 = 4;
    private final int PERIOD6 = 5;
    private final int PERIOD7 = 6;

    // toolbar
    private Toolbar toolbar;

    // nav drawer
    private DrawerLayout navDrawer;

    // user's data
    private String[] userClasses = new String[10];

    // list to fill Classroom class with
    private List<ClassroomClass> classrooms;

    /*
    * on creation of activity
     */
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // initialise and set toolbar as actionbar
        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);

        // initialize drawer layout
        navDrawer = (DrawerLayout) findViewById(R.id.drawer);
        NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);

        // initialize recycler view elements
        RecyclerView mainRecyclerView = (RecyclerView)findViewById(R.id.main_recycler_view);

        // initialize layout manager for recycler view
        RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);

        // adapter for recycler view
        RecyclerView.Adapter mainAdapter= new MainRecyclerAdapter(classrooms);;

        // initialize nav bars
        initNavBars();

        // initialize nav drawer
        initNavDrawer();

        // initialize data for all classes
        initClassData();

        // add layout manager to recycler view
        mainRecyclerView.setLayoutManager(mainLayoutManager);

        // add adapter to recycler view
        mainRecyclerView.setAdapter(mainAdapter);

    }

    /*
    * initializes the class data for each class
    */
    public void initClassData()
    {
        // check if a user is not cached
        ParseUser currentUser = ParseUser.getCurrentUser();
        if (currentUser == null)
        {
            // prompt user to Register screen
            Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intent);
        }

        // query database for user's classes
        final ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
        query.whereEqualTo("student_id", ParseUser.getCurrentUser());

        query.getFirstInBackground(new GetCallback<ParseObject>()
        {
            @Override
            public void done(ParseObject parseObject, ParseException e)
            {
                if (parseObject == null)
                {
                    // retrieved the object
                    userClasses[PERIOD1]= parseObject.getString("first_period");
                    userClasses[PERIOD2]= parseObject.getString("second_period");
                    userClasses[PERIOD3]= parseObject.getString("third_period");
                    userClasses[PERIOD4]= parseObject.getString("fourth_period");
                    userClasses[PERIOD5]= parseObject.getString("fifth_period");
                    userClasses[PERIOD6]= parseObject.getString("sixth_period");
                    userClasses[PERIOD7]= parseObject.getString("seventh_period");
                }
                else
                {
                    // failed lookup. Do something here
                }
            }
        });

        // fill all fields for class periods
        classrooms = new ArrayList<>();

        // titles of classes to add to list
        String[] classTitles = {"First Period", "Second Period", "Third Period", "Fourth Period",
                "Fifth Period", "Sixth Period", "Seventh Period"};

        // iterate over every period to add it to the list
        for (int i = 0; i <= PERIOD7; i++)
        {
            // if period registered was "Nothing" don't add it to list
            //if (!userClasses[i].equals("Nothing"))
            //{
                classrooms.add(new ClassroomClass(userClasses[i], classTitles[i], i + 1));
            //}
        }
    }

    public void initNavDrawer()
    {
        navDrawer = (DrawerLayout) findViewById(R.id.drawer);

        final NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);

        navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
        {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem)
            {
                menuItem.setChecked(true);
                navDrawer.closeDrawers();
                return true;
            }
        });
    }

    private void initNavBars()
    {
       if (toolbar != null)
       {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            toolbar.setNavigationIcon(R.drawable.ic_menu_white);
            toolbar.setNavigationOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    navDrawer.openDrawer(GravityCompat.START);
                }
            });
       }
    }
}

我的数据字段类

package maxbleggi.afstudentplanner;

/*
 * Define the characteristics that all classroom cards have in common
*/
public class ClassroomClass
{

    String className;
    String classPeriod;
    int classNumber;

    public ClassroomClass(String className, String classPeriod, int classNumber)
    {
        this.className = className;
        this.classPeriod = classPeriod;
        this.classNumber = classNumber;
    }

    public String getClassName()
    {
        return className;
    }

    public String getClassPeriod()
    {
        return classPeriod;
    }

    public int getClassNumber()
    {
        return classNumber;
    }
}

最后是我的适配器

package maxbleggi.afstudentplanner;

import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder>
{
    private List<ClassroomClass> classrooms;

    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        // hold data items
        public View view;

        ViewHolder(View itemView)
        {
            super(itemView);
            view = itemView;
        }
    }

    public MainRecyclerAdapter(List<ClassroomClass> classrooms)
    {
        this.classrooms = classrooms;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
    {
        // create a new view
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.main_recycler_view_row, viewGroup, false);

        // set the view's parameters
        ViewHolder pvh = new ViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position)
    {
        // get elements from view
        TextView title = (TextView) viewHolder.view.findViewById(R.id.period_title);
        TextView subtitle = (TextView) viewHolder.view.findViewById(R.id.period_subtitle);

        // retrieve data from data field and put in view
        title.setText(classrooms.get(position).getClassName());
        subtitle.setText(classrooms.get(position).classPeriod);

    }

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


    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView)
    {
        super.onAttachedToRecyclerView(recyclerView);
    }
}

在此处获取项目计数时,我的 MainRecyclerAdapter 中出现 java.lang.NullPointerException

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

感谢任何帮助或评论,感谢所有代码。我只是想确保我是彻底的。

最佳答案

你必须在创建构造函数之前初始化教室数据,所以只需调用

initClassData();

在适配器构造函数之前。

顺便说一句,你应该在 viewholder 构造函数中执行此代码

// get elements from view
        TextView title = (TextView) viewHolder.view.findViewById(R.id.period_title);
        TextView subtitle = (TextView) viewHolder.view.findViewById(R.id.period_subtitle);

然后像这样使用它

holder.title.setText

holder.subtitle.setText

关于java - Recyclerview 适配器中的空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31169517/

相关文章:

java - 差异库的使用

java - 检索枚举中设置的 @JsonProperty 值

Java 货币转换器 GUI

android - 从android终端向蓝牙模块发送数据

java - View.Gone 位于适配器内部,在 onBindViewHolder 中留下空间

java - NfcAdapter 不可为空,但由@Provides @Singleton @javax.annotation.Nullable android.nfc.NfcAdapter 提供

java - 使用 picasso 将图像大小调整为全宽和固定高度

android - 显示重复项的 GridView

java - RecyclerView 以编程方式单击

java - 多个 fragment 需要位置更新