2016-03-05 77 views
0

嗨我的MainActivity我实施了ViewPagerTabLayout与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); 
} 
} 

这里被点击的RecyclerView任何卡时onClicked()方法被调用。 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将总是有相同的回调监听器,当你希望每个人都有自己的。

这就是您遇到此问题的原因。 RatedFragmentPopularFragment都使用RecyclerAdapter。点击图片时,即使在查看PopulareFragmnet时,也会调用RatedFragment的回叫。

RatedFragment然后不添加额外的你正在寻找哪些是造成NullPointerException

为了解决这个问题,从mListener删除静态在RecyclerAdapter

private OnClick mListener; 

所以它成为一个内部类然后从ViewHolder类的定义中删除静态还并且可以访问直接监听器:

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

这样做后,你仍然必须修复RatedFragment,因为它会显示相同的DetailsFragment没有你目前需要的额外。

+0

谢谢这么多:) –

+0

不客气。 –

+0

你能否通过查看我的代码来提出一些最佳实践,我会做些什么错误会对你有帮助 –