2016-06-22 2 views
0

Как исправить мою проблему при попытке использовать RecyclerView. Когда я добавляю 2 строки кода

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

Мой код всегда показывать ошибка

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)  

Как исправить мою проблему? Это выглядит как RecyclerView.setLayoutManager, но я не могу решить мою проблему в одиночку.

Это мой код (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> 

и мой 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(); 
    } 
} 

Может быть, я забыл что-то изменить, пожалуйста, помогите ..

Благодаря

+0

Похоже, ваш 'recyclerView' является нулевым – ArbenMaloku

+0

Да @ArbenMaloku может быть, вы можете показать мне, как исправить мой код –

+0

Ваш' activity_main.xml' не имеет RecyclerView. Переместите его туда или выполните свой логин в Фрагменте –

ответ

0
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. 

Попробуйте так, чтобы избежать Нулевой исключение разыменования

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

Вашего recyclerView является недействительным. Поскольку RecyclerView добавляется только тогда, когда в вашу деятельность загружается 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(); 

Вы должны сделать findViewById после этого. Однако, fragmentTransaction.commit(); - это процесс асинхронного процесса. Содержимое фрагмента может быть недоступно сразу после этого. Итак, вам нужно позвонить fragmentTransaction.commitNow(), чтобы убедиться, что фрагмент добавлен к активности.

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

Это не очень хорошая идея, чтобы найти фрагмент с уровня активности. Одна из причин заключается в том, чтобы избежать ситуации, с которой вы сейчас сталкиваетесь, поскольку фрагментарный контент не может быть гарантирован в активности.

Лучший способ найти и установить содержание вид внутри фрагмента onViewCreated

Если данные получают от деятельности, вы можете передать данные фрагмента из деятельности.

См, такие темы, как «связь между фрагментом и деятельности» https://developer.android.com/training/basics/fragments/communicating.html

+0

Привет @OnJohn Я пытаюсь найти решение findViewById afterDefaultFragment, но всегда такая же ошибка –

+0

Я предполагаю, что это тоже может произойти. Поскольку 'fragmentTransaction.commit();' является асинхронным процессом, это означает, что фрагмент может быть недоступен немедленно. Думаю, вам стоит попытаться найти представление в уровне фрагмента. Позвольте мне также обновить ответ – OnJohn

+0

Проще всего вызвать 'fragmentTransaction.commitNow()' для обеспечения добавления фрагмента. Проверьте мое обновление :) – OnJohn

0

Либо переместите fragment_home.xml код внутри файла main.xml, если вы хотите recyclerView внутри вашего activity. т.е.

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> 

ИЛИ

добавить Fragment к вашему activity, который раздувает fragment_home.xml и переместить код recyclerView инициализации вашей fragment. то есть ниже код в вашем фрагменте:

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

Привет @ himanshu1496 Я пробую ваше первое решение и работает. Но когда я нажимаю на другое меню (например, второе меню), представление становится сложным. см. https://s32.postimg.org/qmro4tpwl/error.png –

+0

Да, это произойдет потому, что вы должны загружать один и тот же «frameLayout», теперь, если вы хотите продолжить первое решение, установите цвет фона белый, для просмотра, который находится сверху, и сделать родительский макет кликабельным, чтобы пользователь не заметил, что представление сложено. – himanshu1496

+0

вторым решением было бы загрузить новый фрагмент и разместить recyclerView там, и каждый раз, когда вы хотите загрузить другой фрагмент, просто замените первый фрагмент. – himanshu1496

Смежные вопросы