[英]'boolean android.support.v7.widget.RecyclerView$LayoutManager.canScrollVertically()'
How to fix my issue when I try to use RecyclerView . 当我尝试使用RecyclerView时如何解决我的问题。 When I add 2 line of code 当我添加2行代码
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. 看起来像RecyclerView.setLayoutManager
但是我不能独自解决问题。
This is my code ( ChannelAdapter.java ) 这是我的代码( 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 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 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 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 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 和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 谢谢
Your recyclerView
is null. 您的recyclerView
为空。 Because the RecyclerView is only added when fragment_home.xml
is loaded to your activity. 因为只有在将fragment_home.xml
加载到您的活动中时才添加RecyclerView。
That mean it is ready after (assuming your DefaultFragment is inflate fragment_home.xml
) 这意味着它已经准备好了(假设您的DefaultFragment膨胀了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. 之后,您应该执行findViewById。 However, fragmentTransaction.commit();
但是, 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. 因此,您将需要调用fragmentTransaction.commitNow()
以确保将片段添加到活动中。
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
更好的方法是在片段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 参见诸如“片段与活动之间的通信”之类的主题https://developer.android.com/training/basics/fragments/communicating.html
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));
.....
.....
.....
}
Either move fragment_home.xml
code inside your main.xml
file, If you want recyclerView
inside your activity
. 如果要在activity
放入recyclerView
,请在您的main.xml
文件中移动fragment_home.xml
代码。 ie 即
main.xml 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
. 添加一个Fragment
到你的activity
,其膨胀fragment_home.xml
和移动recyclerView
初始化代码到你的fragment
。 ie Below code in your fragment: 即下面的代码在您的片段中:
recyclerView = (RecyclerView) rootview.findViewById(R.id.movies_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.