2017-04-26 10 views
-1

我知道這個問題非常多,但是我搜索了很多,我無法理解這個問題。我創建一個接口,用於回收視圖上的特定貨物處理點擊聽衆在回收站項目中獲取空指針異常單擊偵聽器接口

這裏是我的班

MovieAdapter.java

package com.example.vikas.movie.adapter; 

/** 
* Created by vikas on 23/4/17. 
*/ 
import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.text.TextUtils; 
import android.util.Log; 
import android.view.HapticFeedbackConstants; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

import com.bumptech.glide.Glide; 
import com.bumptech.glide.load.engine.DiskCacheStrategy; 
import com.example.vikas.movie.R; 
import com.example.vikas.movie.helper.CircleTransformation; 
import com.example.vikas.movie.model.Movie; 

import java.util.List; 
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> 
{ 
    private static final String TAG=MovieAdapter.class.getSimpleName(); 

    private List<Movie> movies; 
    private int rowLayout; 
    private Context context; 
    private MovieAdapterListener listener; 


    public static class MovieViewHolder extends RecyclerView.ViewHolder 
    { 
     RelativeLayout moviesLayout; 
     TextView movieTitle; 
     TextView data; 
     TextView movieDescription; 
     TextView rating; 
     ImageView imageView; 


     public MovieViewHolder(View v) 
     { 
      super(v); 
      moviesLayout = (RelativeLayout) v.findViewById(R.id.movie_layout); 
      movieTitle = (TextView) v.findViewById(R.id.title); 
      data = (TextView) v.findViewById(R.id.subtitle); 
      movieDescription = (TextView) v.findViewById(R.id.description); 
      rating = (TextView) v.findViewById(R.id.rating); 
      imageView=(ImageView)v.findViewById(R.id.movie_image); 
     } 



    } 

    public MovieAdapter(List<Movie> movies, int rowLayout, Context context) 
    { 
     this.movies = movies; 
     this.rowLayout = rowLayout; 
     this.context = context; 
    } 

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


    @Override 
    public void onBindViewHolder(MovieViewHolder holder, final int position) 
    { 
     Movie movie= movies.get(position); 
     holder.movieTitle.setText(movies.get(position).getTitle()); 
     holder.data.setText(movies.get(position).getReleaseDate()); 
     holder.movieDescription.setText(movies.get(position).getOverview()); 
     holder.rating.setText(movies.get(position).getvote_average().toString()); 
     MovieImage(holder,movie); 
     applyClickEvents(holder,position); 


    } 
    private void applyClickEvents(MovieViewHolder holder,final int position) 
    { 
     holder.moviesLayout.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View view) 
      { 
       listener.onItemClicked(position); 
      } 
     }); 


    } 


    private void MovieImage(MovieViewHolder holder,Movie movie) 
    { 
     String base_URL="https://image.tmdb.org/t/p/"; 
     String size_Image="w500"; 
     String file_Path=movie.getPosterPath(); 

     StringBuilder image_Path=new StringBuilder(); 
     image_Path.append(base_URL).append(size_Image).append(file_Path); 
     Log.d(TAG,"movie genere ids "+movie.getGenreIds()); 
     Log.d(TAG,"movie relese date "+movie.getReleaseDate()); 




     if(!TextUtils.isEmpty(image_Path)) 
     { 
      Glide.with(context).load(image_Path.toString()) 
        .thumbnail(0.5f) 
        .crossFade() 
        .transform(new CircleTransformation(context)) 
        .diskCacheStrategy(DiskCacheStrategy.ALL) 
        .into(holder.imageView); 
     } 
     else 
     { 
      holder.imageView.setImageResource(R.drawable.circle); 
     } 

    } 

    public interface MovieAdapterListener 
    { 
     void onItemClicked(int position); 

    } 


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

MainActivity.java在我implenting接口和重寫我在界面中聲明的方法。

package com.example.vikas.movie.activity; 

import android.support.design.widget.CoordinatorLayout; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.DefaultItemAnimator; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.widget.Toast; 


import com.example.vikas.movie.R; 
import com.example.vikas.movie.adapter.MovieAdapter; 
import com.example.vikas.movie.model.Movie; 
import com.example.vikas.movie.model.MoviesResponse; 
import com.example.vikas.movie.rest.ApiClient; 
import com.example.vikas.movie.rest.ApiInterface; 

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

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

public class MainActivity extends AppCompatActivity implements MovieAdapter.MovieAdapterListener 
{ 

    private static final String TAG=MainActivity.class.getSimpleName(); 
    //get which got from web API 
    private final static String API_KEY="xxxxx"; 
    private CoordinatorLayout coordinatorLayout; 
    // private MovieAdapter movieAdapter; 
    private RecyclerView recyclerView; 
    private List<Movie> movieList = new ArrayList<>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinate_layout); 

     if(API_KEY.isEmpty()) 
     { 
      Snackbar snackbar = Snackbar 
        .make(coordinatorLayout, "Please Enter The key", Snackbar.LENGTH_LONG); 

      snackbar.show(); 
      return; 
     } 
     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 



     ApiInterface apiInterface= ApiClient.getClient().create(ApiInterface.class); 
     Call<MoviesResponse> call= apiInterface.getNowPlayingMovies(API_KEY); 
     call.enqueue(new Callback<MoviesResponse>() 
     { 
      @Override 
      public void onResponse(Call<MoviesResponse> call, Response<MoviesResponse> response) 
      { 

       movieList= response.body().getResults(); 
       Log.d(TAG, "Number of movies received: " + movieList.size()); 
       recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext())); 
       // movieAdapter.notifyDataSetChanged(); 
       // Log.d(TAG, "Number of movies received: " + movieList.); 


      } 

      @Override 
      public void onFailure(Call<MoviesResponse> call, Throwable t) 
      { 
       Snackbar snackbar = Snackbar 
         .make(coordinatorLayout, "Please Check your Internet Connection", Snackbar.LENGTH_LONG); 

       snackbar.show(); 
       Log.e(TAG, t.toString()); 

      } 
     }); 

    } 

    @Override 
    public void onItemClicked(int position) 
    { 
     Movie movie = movieList.get(position); 
     movie.getGenreIds(); 
     movie.getId(); 
     Toast.makeText(getApplicationContext(), "id: "+ movie.getId(), Toast.LENGTH_SHORT).show(); 
    } 


} 

我得到的logcat這樣

FATAL EXCEPTION: main 
                     Process: com.example.vikas.movie, PID: 23565 
                     java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.vikas.movie.adapter.MovieAdapter$MovieAdapterListener.onItemClicked(int)' on a null object reference 
                      at com.example.vikas.movie.adapter.MovieAdapter$1.onClick(MovieAdapter.java:97) 
                      at android.view.View.performClick(View.java:5205) 
                      at android.view.View$PerformClick.run(View.java:21164) 
                      at android.os.Handler.handleCallback(Handler.java:739) 
                      at android.os.Handler.dispatchMessage(Handler.java:95) 
                      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) 
04-26 23:56:00.538 23565-23565/com.example.vikas.movie I/Process: Sending signal. PID: 23565 SIG: 9 

請人幫忙,我無法理解的問題。

+0

調用setAdapter()在runOnUIThread()。 –

+0

你沒有在你的適配器中通過任何引用或初始化你的監聽器 –

回答

1

你得到NullPointerException我你的界面監聽器。

在適配器類初始化你的界面聽衆:

public MovieAdapter(List<Movie> movies, int rowLayout, Context context) { 
    this.movies = movies; 
    this.rowLayout = rowLayout; 
    this.context = context; 
    listener = (MovieAdapterListener) context; //add this 

} 

編輯

而且現在設置使用適配器:

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, MainActivity.this)); 
+0

我得到這個異常後,我已經做了你已經建議java.lang.ClassCastException更改:android.app.Application不能轉換爲com.example.vikas.movi​​e.adapter.MovieAdapter $ MovieAdapterListener ,位於com.example.vikas.movi​​e.adapter.MovieAdapter。 (MovieAdapter.java:66) at com.example.vikas.movi​​e.activity.MainActivity $ 1。onResponse(MainActivity.java:70) – Vikas

+0

我編輯了我的答案.... – rafsanahmad007

+0

非常感謝你挽救了我的一天 – Vikas

2

發生這種情況是因爲您尚未初始化「聽衆」。當您在MainActivity中創建新的MovieAdapter並將其分配給「偵聽器」時,必須傳遞偵聽器。

MovieAdapter.java,改變公衆MovieAdapter()到

public MovieAdapter(List<Movie> movies, int rowLayout, Context context, MovieAdapterListener listener) 
{ 
    this.movies = movies; 
    this.rowLayout = rowLayout; 
    this.context = context; 
    this.listener=listener; 
} 

和MainActivity.java, 改線

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext())); 

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext(),listener)); 
//change "listener into the name of MovieAdapterListener object" 
+0

我們如何創建一個接口對象 – Vikas

1

我相信MovieAdapter應該初始化監聽成員:

public MovieAdapter(List<Movie> movies, int rowLayout, Context context, MovieAdapterListener lstn) 
{ 
    this.movies = movies; 
    this.rowLayout = rowLayout; 
    this.context = context; 
    this.listener = lstn; 
} 

而且在MainActivity當你設置適配器,因爲它實現MovieAdapter.MovieAdapterListener你應該通過它的另一個實例:

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, this, this));