尝试使用CardView和RecyclerView

时间:2018-01-28 18:45:59

标签: java android android-recyclerview android-cardview

我现在有一个非常基本的应用程序的开头。它只有一个主要活动,它有一个导航抽屉和一张卡。当我尝试调试应用程序时,我收到以下错误:

  

java.lang.NullPointerException:尝试调用虚方法' boolean android.support.v7.widget.RecyclerView $ ViewHolder.shouldIgnore()'在null对象引用上。以下是代码:

MainActivity:

public class MainActivity extends AppCompatActivity
{
    private DrawerLayout mDrawerLayout;

    private RecyclerView recyclerView;
    private ScoreCardAdapter adapter;
    private List<ScoreCard> scoreCardList;

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

        //Setting up the custom toolbar
        Toolbar customToolbar = findViewById(R.id.custom_toolbar);
        setSupportActionBar(customToolbar);
        getSupportActionBar().setTitle(null);
        customToolbar.setBackgroundColor(Color.TRANSPARENT);

        //Creating the menu icon in the appbar
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null)
        {
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
            actionBar.setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);
        }

        mDrawerLayout = findViewById(R.id.drawer_layout);

        // Initializing Drawer Layout and ActionBarToggle
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,customToolbar,R.string.openDrawer, R.string.closeDrawer)
        {
            @Override
            public void onDrawerClosed(View drawerView)
            {
                // Code here will be triggered once the drawer closes as we don't want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we don't want anything to happen so we leave this blank
                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        mDrawerLayout.addDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessay or else your hamburger icon wont show up
        actionBarDrawerToggle.syncState();

        scoreCardList = new ArrayList<>();
        recyclerView = findViewById(R.id.recycler_view);
        adapter = new ScoreCardAdapter(this, scoreCardList);

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(adapter);


        scoreCardList.add(new ScoreCard("Sunday, 28th January 2018", R.drawable.launcher_logo, "3 -- 2", R.drawable.annan_athletic_fc_logo, "14:00, Forthbank Stadium"));


    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        //noinspection SimplifiableIfStatement

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed()
    {
        if (mDrawerLayout.isDrawerOpen(GravityCompat.START))
        {
            mDrawerLayout.closeDrawer(GravityCompat.START);
        }
        else
        {
            super.onBackPressed();
        }
    }
}

适配器:

public class ScoreCardAdapter extends RecyclerView.Adapter<ScoreCardAdapter.ScoreCardViewHolder>
{
    private Context mCtx;
    private List<ScoreCard> scoreCardList;

    public class ScoreCardViewHolder extends RecyclerView.ViewHolder
    {
        public TextView dateTextView;
        public ImageView homeTeamLogoImageView;
        public TextView scoreTextView;
        public ImageView enemyTeamLogoImageView;
        public TextView timeAndLocationTextView;

        public ScoreCardViewHolder(View view)
        {
            super(view);

            dateTextView = itemView.findViewById(R.id.date_textview);
            homeTeamLogoImageView = itemView.findViewById(R.id.home_team_logo_imageview);
            scoreTextView = itemView.findViewById(R.id.score_textview);
            enemyTeamLogoImageView = itemView.findViewById(R.id.enemy_team_logo_imageview);
            timeAndLocationTextView = itemView.findViewById(R.id.time_and_location_textview);
        }
    }

    public ScoreCardAdapter(Context mCtx, List<ScoreCard> scoreCardList)
    {
        this.mCtx = mCtx;
        this.scoreCardList = scoreCardList;
    }

    @Override
    public ScoreCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_card_layout, parent, false);
        return new ScoreCardViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final ScoreCardViewHolder holder, int position)
    {
        ScoreCard scoreCard = scoreCardList.get(position);

        holder.dateTextView.setText(scoreCard.getDate());
        holder.scoreTextView.setText(scoreCard.getScore());
        holder.timeAndLocationTextView.setText(scoreCard.getTimeAndLocation());

        holder.homeTeamLogoImageView.setImageDrawable(mCtx.getResources().getDrawable(scoreCard.getHomeTeamLogo(), null));
        holder.enemyTeamLogoImageView.setImageDrawable(mCtx.getResources().getDrawable(scoreCard.getEnemyTeamLogo(), null));
    }

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


}

主XML:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.application.andrewhaines.stirlingalbionfc.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager">

        <android.support.v7.widget.Toolbar
            android:id="@+id/custom_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/SAFCRed"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu_list"
        app:headerLayout="@layout/nav_drawer_layout"
        android:theme="@style/NavigationDrawerStyle">
    </android.support.design.widget.NavigationView>

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

CardXML:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/score_card_overall_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_margin="5dp"
        android:elevation="3dp">

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

            <TextView
                android:id="@+id/date_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:fontFamily="sans-serif"
                android:textAllCaps="true"
                android:textSize="16sp"/>

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

                <ImageView
                    android:id="@+id/home_team_logo_imageview"
                    android:layout_width="0dp"
                    android:layout_height="100dp"
                    android:layout_marginStart="10dp"
                    android:layout_weight="1"
                    android:contentDescription="home team logo"
                    android:scaleType="fitCenter"/>

                <TextView
                    android:id="@+id/score_textview"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_weight="1"
                    android:fontFamily="sans-serif"
                    android:gravity="center_horizontal"
                    android:textSize="20sp"/>

                <ImageView
                    android:id="@+id/enemy_team_logo_imageview"
                    android:layout_width="0dp"
                    android:layout_height="100dp"
                    android:layout_marginEnd="10dp"
                    android:layout_weight="1"
                    android:contentDescription="enemy team logo"
                    android:scaleType="fitCenter"/>

            </LinearLayout>

            <TextView
                android:id="@+id/time_and_location_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:fontFamily="sans-serif"
                android:textAllCaps="true"
                android:textSize="14sp"/>



        </LinearLayout>

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

</LinearLayout>

logcat的:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.application.andrewhaines.stirlingalbionfc, PID: 16411
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.application.andrewhaines.stirlingalbionfc/com.application.andrewhaines.stirlingalbionfc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
                      at android.support.v7.widget.RecyclerView$LayoutManager.removeAndRecycleAllViews(RecyclerView.java:9728)
                      at android.support.v7.widget.RecyclerView.setLayoutManager(RecyclerView.java:1220)
                      at com.application.andrewhaines.stirlingalbionfc.MainActivity.onCreate(MainActivity.java:79)
                      at android.app.Activity.performCreate(Activity.java:6679)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                      at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6119) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

我查看了其他NullPointerExcpetion线程,但是他们没有帮助!

2 个答案:

答案 0 :(得分:0)

看起来你传递的布局管理器存在问题。

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setHasFixedSize(true);
    recyclerView.setAdapter(adapter);

相反,您可以尝试将其用于布局管理器。

recyclerView.setLayoutManager(new LinearLayoutManager(this));

答案 1 :(得分:0)

好的,所以我真的不知道为什么会这样,但我所做的只是交换了这段代码:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.application.andrewhaines.stirlingalbionfc.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager">

        <android.support.v7.widget.Toolbar
            android:id="@+id/custom_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/SAFCRed"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu_list"
        app:headerLayout="@layout/nav_drawer_layout"
        android:theme="@style/NavigationDrawerStyle">
    </android.support.design.widget.NavigationView>

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

使用此代码:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.application.andrewhaines.stirlingalbionfc.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/custom_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/SAFCRed"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager">

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

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu_list"
        app:headerLayout="@layout/nav_drawer_layout"
        android:theme="@style/NavigationDrawerStyle">
    </android.support.design.widget.NavigationView>

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

因此,如果有人可以让我知道为什么将工具栏作为DrawerLayout的第一个子项然后再使用RecyclerView,那么第二个就可以使用RecyclerView作为第一个孩子然后将工具栏作为第二个孩子而不是?