'boolean android.support.v7.widget.RecyclerView$LayoutManager.canScrollVertically()'

谁说我不能喝 提交于 2019-12-13 06:13:40

问题


How to fix my issue when I try to use RecyclerView. When I add 2 line of code

recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

My code always show error

06-22 19:52:25.801 19743-19743/com.transvision.bertho.transvisiondashboardapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.transvision.bertho.transvisiondashboardapp, PID: 19743
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.transvision.bertho.transvisiondashboardapp/com.transvision.bertho.transvisiondashboardapp.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at com.transvision.bertho.transvisiondashboardapp.MainActivity.onCreate(MainActivity.java:53)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

How to fix my issue? It looks like RecyclerView.setLayoutManager but I cant resolve my issue alone.

This is my code (ChannelAdapter.java)

package adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.transvision.bertho.transvisiondashboardapp.R;

import java.util.List;

import model.Channel;


public class ChannelAdapter extends RecyclerView.Adapter<ChannelAdapter.ChannelViewHolder> {

    private List<Channel> channels;
    private int rowLayout;
    private Context context;

    public static class ChannelViewHolder extends RecyclerView.ViewHolder {

        LinearLayout moviesLayout;
        TextView movieTitle;
        TextView data;
        TextView movieDescription;
        TextView rating;

        TextView name;
        TextView code;
        TextView description;
        TextView number;
        TextView definition;
        TextView paket;
        ImageView logo;

        public ChannelViewHolder(View v) {
            super(v);
            moviesLayout = (LinearLayout) v.findViewById(R.id.movies_layout);
            name = (TextView) v.findViewById(R.id.title);
            definition = (TextView) v.findViewById(R.id.subtitle);
            description = (TextView) v.findViewById(R.id.description);
//            rating = (TextView) v.findViewById(R.id.rating);
        }
    }

    public ChannelAdapter(List<Channel> channels, int rowLayout, Context context) {
        this.channels = channels;
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public ChannelAdapter.ChannelViewHolder onCreateViewHolder(ViewGroup parent,
                                                            int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new ChannelViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ChannelViewHolder holder, final int position) {
        holder.name.setText(channels.get(position).getName());
        holder.definition.setText(channels.get(position).getDefinition());
        holder.description.setText(channels.get(position).getDescription());
//        holder.rating.setText(channels.get(position).getVoteAverage().toString());
    }

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

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.transvision.bertho.transvisiondashboardapp.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

main.xml

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

    <FrameLayout
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

fragment_home.xml

<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:orientation="vertical"
    tools:context="com.transvision.bertho.transvisiondashboardapp.MainActivity">

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

</RelativeLayout>

and My MainActivity.java

package com.transvision.bertho.transvisiondashboardapp;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
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.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import java.util.List;

import adapter.ChannelAdapter;
import model.Channel;
import model.ChannelResponse;
import model.Movie;
import model.MoviesResponse;
import page.DefaultFragment;
import page.HomeFragment;
import page.ProfileFragment;
import rest.ApiClient;
import rest.ApiInterface;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

    private static final String TAG = MainActivity.class.getSimpleName();

    private final static String API_KEY = "7e8f60e325cd06e164799af1e317d7a7";

    private RecyclerView recyclerView;

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

        recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        Fragment fragment = null;
        fragment = new DefaultFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.root, fragment);
        fragmentTransaction.commit();

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @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.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        Fragment fragment = null;
        String title = getString(R.string.app_name);

        if (id == R.id.nav_camera) {
            fragment = new HomeFragment();
            title = "Home";
            getChannelData();
        } else if (id == R.id.nav_gallery) {
            fragment = new ProfileFragment();
            title = "Profile";
        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.root, fragment);
            fragmentTransaction.commit();

            // set the toolbar title
            getSupportActionBar().setTitle(title);
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    public void getChannelData() {
        ApiInterface apiService = ApiClient.getChannel().create(ApiInterface.class);
        Call<ChannelResponse> call = apiService.getItems();

        call.enqueue(new Callback<ChannelResponse>() {
            @Override
            public void onResponse(Call<ChannelResponse> call, Response<ChannelResponse> response) {
                int statusCode = response.code();
                List<Channel> channel = response.body().getItems();
                Log.d(TAG, "NUMBER OF MOVIES RECEIVED : " + channel.size());
                recyclerView.setAdapter(new ChannelAdapter(channel, R.layout.list_channel, getApplicationContext()));
            }

            @Override
            public void onFailure(Call<ChannelResponse> call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }


    public void showToast(String output){
        Toast.makeText(this.getBaseContext(), output, Toast.LENGTH_SHORT).show();
    }
}

Maybe I forgot to change something, please help...

Thanks


回答1:


Your recyclerView is null. Because the RecyclerView is only added when fragment_home.xml is loaded to your activity.

That mean it is ready after (assuming your DefaultFragment is inflate fragment_home.xml)

Fragment fragment = null;
fragment = new DefaultFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.root, fragment);
fragmentTransaction.commit();

You should do the findViewById after that. However, fragmentTransaction.commit(); is an async process. The fragment content may not be available immediately after that. So, you will need to call fragmentTransaction.commitNow() to make sure the fragment is added to activity.

recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

It is not a very good idea to find fragment's view from the activity level. One of the reason is to avoid the situation like you are facing now as fragment content cannot be guaranteed in activity.

The better way is to find and set view content inside the fragment onViewCreated

If your data is get from activity, you can still pass the data to fragment from activity.

See, topics like "communication between fragment and activity" https://developer.android.com/training/basics/fragments/communicating.html




回答2:


recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
// The above line doesnot throw null pointer exception, since you can cast null to any object. Refer this post - http://stackoverflow.com/questions/18723596/no-exception-while-type-casting-with-a-null-in-java
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// The above line will throw null pointer exception, since here we are accessing the null object and invoking a method on that null object.

Try like this to avoid the null pointer exception

 recyclerView = (RecyclerView) findViewById(R.id.movies_recycler_view);
 if(recyclerView != null) {     
     recyclerView.setLayoutManager(new LinearLayoutManager(this));
     .....
     .....
     .....
 }



回答3:


Either move fragment_home.xml code inside your main.xml file, If you want recyclerView inside your activity. i.e.

main.xml

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

<FrameLayout
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

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

</FrameLayout>

</LinearLayout>

OR

add a Fragment to your activity which inflates fragment_home.xml and move recyclerView initialization code to your fragment. i.e. Below code in your fragment:

recyclerView = (RecyclerView) rootview.findViewById(R.id.movies_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));


来源:https://stackoverflow.com/questions/37969080/boolean-android-support-v7-widget-recyclerviewlayoutmanager-canscrollverticall

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!