2016-03-05 3 views
0

Привет в моем MainActivity Я внедрил ViewPager с TabLayout с 3 вкладками, и каждая страница просмотра начинает новый фрагмент. Я показываю карты в виде сетки в каждом фрагменте, и когда нажимается карта, начинается DetailActivtiy. Я начинаю работу с деталями из Фрагментов, но когда я пытаюсь добавить дополнительные данные в Intent, начнем с детальной деятельности. Я получаю NullPointerException. Я пытался отлаживать код, но я не могу найти, где проблема.Намерение putExtra() не работает

Вот мой код:

PopularFragment (один из расположения вкладок в 3 вкладки)

public class PopularFragment extends Fragment implements PosterTask.GetPoster,RecyclerAdapter.OnClick { 
private RecyclerAdapter mRecyclerAdapter; 
private ProgressDialog mProgressBar; 
private ArrayList<Movie> movies; 

public PopularFragment() { 
    // Required empty public constructor 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_popular, container, false); 
    //Show progress bar 
    showProgressBar(); 
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); 
    //Setting layout manager 
    recyclerView.setLayoutManager(new GridLayoutManager(inflater.getContext(), 2)); 
    //Setting adapter 
    mRecyclerAdapter = new RecyclerAdapter(inflater.getContext()); 
    recyclerView.setAdapter(mRecyclerAdapter); 
    return view; 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    //Starting asyncTask 
    new PosterTask(this).execute(buildUrl().toString()); 
    //Setting listener to cards 
    mRecyclerAdapter.setOnClickListener(this); 
} 

//Building url 
private Uri buildUrl(){ 
    //Building url 
    String api_key = "api_key"; 
    return Uri.parse(Utility.POPULAR_URL).buildUpon() 
      .appendQueryParameter(api_key, getString(R.string.API_KEY)) 
      .build(); 
} 

//Called after getting posters url's 
@Override 
public void onPosterCompleted(ArrayList<Movie> movies) { 
    ArrayList<String> poster = new ArrayList<>(); 
    for(int i=0;i<movies.size();i++){ 
     poster.add(movies.get(i).getPoster()); 
    } 
    //Passing data to adapter 
    mRecyclerAdapter.setPoster(poster); 
    //Removing progress bar 
    mProgressBar.hide(); 
    this.movies = movies; 
} 

//Showing progress bar 
private void showProgressBar(){ 
    mProgressBar = new ProgressDialog(getContext()); 
    mProgressBar.setMessage("Fetching data..."); 
    mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    mProgressBar.show(); 
} 

@Override 
public void onClicked(int position, View v) { 
    //Starting detail activity 
    Intent intent = new Intent(getActivity(), DetailActivity.class); 
    intent.putExtra(Utility.INTENT_CONSTANT, "sahil"); 
    startActivity(intent); 
} 
} 

Здесь onClicked() метод вызывается, когда любая карта RecyclerView нажата. RecyclerAdapter:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> { 
private Context mContext; 
private ArrayList<String> mPosters; 
private static OnClick mListener; 

//Listener listening clicks 
public interface OnClick{ 
    void onClicked(int position, View v); 
} 

public RecyclerAdapter(Context context){ 
    mContext = context; 
} 

//Set poster url 
public void setPoster(ArrayList<String> poster){ 
    mPosters = poster; 
    notifyDataSetChanged(); 
} 

//Set listener 
public void setOnClickListener(OnClick listener){ 
    mListener = listener; 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(mContext).inflate(R.layout.card_layout, parent, false); 
    return new ViewHolder(view); 
} 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    //Loading url images to image view in cards 
    Picasso.with(mContext).load(mPosters.get(position)).into(holder.imageView); 
} 

@Override 
public int getItemCount() { 
    if(mPosters!=null) { 
     return mPosters.size(); 
    } 
    return 0; 
} 

//View holder for adapter 
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ 
    private ImageView imageView; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     imageView = (ImageView) itemView.findViewById(R.id.card_image); 
     imageView.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     mListener.onClicked(getPosition(), v); 
    } 
} 
} 

Когда я начинаю DetailActivity без ввода дополнительных в Intent он работает, но когда я ставлю дополнительный в Intent и попытаться получить его в DetailActivity я получаю NullPointerException. В DetailFragment (удерживаемой DetailActivity я пытаюсь получить намерения, как):

//Exception:Detailfragment: 
public class DetailFragment extends Fragment implements TrailerRecyclerAdapter.OnClick,TrailerTask.TrailerCompleted { 
@Bind(R.id.movie_title)TextView titleView; 
@Bind(R.id.movie_date)TextView dateView; 
@Bind(R.id.movie_image)ImageView imageView; 
@Bind(R.id.movie_vote_avg)TextView voteView; 
@Bind(R.id.movie_votes)TextView totalView; 
@Bind(R.id.favorite_button)Button favButton; 
@Bind(R.id.trailer_view)RecyclerView trailerView; 
@Bind(R.id.review_view)RecyclerView reviewView; 
private TrailerRecyclerAdapter mTrailerAdapter; 
private ArrayList<String> mTrailers; 

public DetailFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_detail, container, false); 
    //Binding views 
    ButterKnife.bind(this, view); 
    //Getting clicked movie 
// Movie movie = getActivity().getIntent().getParcelableExtra(Utility.INTENT_CONSTANT); 
    //Starting asyncTask 
// new TrailerTask(this).execute(movie.getId()); 
    //Binding data 
// bindData(movie); 
    Log.v("title", getActivity().getIntent().getStringExtra(Utility.INTENT_CONSTANT)); 
    return view; 
} 

//Binds data to views 
/* 
private void bindData(Movie movie){ 
    titleView.setText(movie.getTitle()); 
    dateView.setText(movie.getDate()); 
    Picasso.with(getContext()).load(movie.getBack_poster()).into(imageView); 
    voteView.setText(String.valueOf(movie.getVote_avg())); 
    String total = getString(R.string.before) + movie.getTotal_votes() + getString(R.string.after); 
    totalView.setText(total); 
    //Setting adapter to trailerView 
    mTrailerAdapter = new TrailerRecyclerAdapter(getContext()); 
    trailerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false)); 
    trailerView.setAdapter(mTrailerAdapter); 
} 
*/ 

@Override 
public void onClicked(int position, View v) { 
//Building intent 
    Uri uri = Uri.parse(mTrailers.get(position)).buildUpon().build(); 
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setData(uri); 
    if (intent.resolveActivity(getActivity().getPackageManager()) != null) { 
     startActivity(intent); 
    } 
} 

@Override 
public void onTrailerCompleted(ArrayList<String> trailers, ArrayList<String> trailer_posters) { 
    mTrailers = trailers; 
    mTrailerAdapter.setPoster(trailer_posters); 
} 
} 

Вот Github repo

Logcat:

E/AndroidRuntime: FATAL EXCEPTION: main 
                     Process: com.example.android.movies, PID: 14578 
                     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.movies/com.example.android.movies.DetailActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390) 
                      at android.app.ActivityThread.access$800(ActivityThread.java:151) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
                      at android.os.Handler.dispatchMessage(Handler.java:110) 
                      at android.os.Looper.loop(Looper.java:193) 
                      at android.app.ActivityThread.main(ActivityThread.java:5292) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) 
                      at dalvik.system.NativeStart.main(Native Method) 
                     Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment 
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713) 
                      at android.view.LayoutInflater.parseInclude(LayoutInflater.java:816) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:745) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
                      at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
                      at com.example.android.movies.DetailActivity.onCreate(DetailActivity.java:14) 
                      at android.app.Activity.performCreate(Activity.java:5292) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)  
                      at android.app.ActivityThread.access$800(ActivityThread.java:151)  
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)  
                      at android.os.Handler.dispatchMessage(Handler.java:110)  
                      at android.os.Looper.loop(Looper.java:193)  
                      at android.app.ActivityThread.main(ActivityThread.java:5292)  
                      at java.lang.reflect.Method.invokeNative(Native Method)  
                      at java.lang.reflect.Method.invoke(Method.java:515)  
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)  
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)  
                      at dalvik.system.NativeStart.main(Native Method)  
                     Caused by: java.lang.NullPointerException: println needs a message 
                      at android.util.Log.println_native(Native Method) 
                      at android.util.Log.v(Log.java:118) 
                      at com.example.android.movies.DetailFragment.onCreateView(DetailFragment.java:54) 
                      at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962) 
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036) 
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1226) 
                      at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1328) 
                      at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2284) 
                      at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111) 
                      at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:314) 
                      at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31) 
                      at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79) 
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689) 
                      at android.view.LayoutInflater.parseInclude(LayoutInflater.java:816)  
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:745)  
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:492)  
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  
                      at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)  
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)  
                      at com.example.android.movies.DetailActivity.onCreate(DetailActivity.java:14)  
                      at android.app.Activity.performCreate(Activity.java:5292)  
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)  
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302)  
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)  
                      at android.app.ActivityThread.access$800(ActivityThread.java:151)  
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)  
                      at android.os.Handler.dispatchMessage(Handler.java:110)  
                      at android.os.Looper.loop(Looper.java:193)  
                      at android.app.ActivityThread.main(ActivityThread.java:5292)  
                      at java.lang.reflect.Method.invokeNative(Native Method)  
                      at java.lang.reflect.Method.invoke(Method.java:515)  
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)  
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)  
                      at dalvik.system.NativeStart.main(Native Method)  
+1

Столбец следа NPE (ошибка logcat) – Vasiliy

+0

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

+0

Это ошибка Log.v (""), когда я пытаюсь напечатать значение намерения –

ответ

1

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

Именно поэтому вы столкнулись с этой проблемой. RatedFragment и PopularFragment оба используют RecyclerAdapter. Когда вы нажимаете на изображение, обратный вызов из вашего RatedFragment будет вызываться даже при просмотре PopulareFragmnet.

RatedFragment не добавляет лишний вы ищете, что вызывает NullPointerException.

Чтобы исправить это удалить статический из mListener в RecyclerAdapter:

private OnClick mListener; 

Затем удалить статический также из определения ViewHolder класса, так что становится внутренним классом и может получить доступ к слушателю непосредственно:

public class ViewHolder extends RecyclerView.ViewHolder 
     implements View.OnClickListener { 

После этого вам все равно придется исправить RatedFragment, так как он отобразит тот же DetailsFragment без дополнительной необходимости, которую вы в настоящее время требуете.

+0

Спасибо большое :) –

+0

Добро пожаловать. –

+0

Можете ли вы предложить несколько лучших практик, увидев мой код, какие ошибки я делаю, это действительно поможет –

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