意图putExtra()不起作用

时间:2016-03-05 17:43:45

标签: java android android-fragments android-intent

您好MainActivity我使用ViewPager TabLayout实施了3个标签,每个视图页面都会启动新的片段。我在每个片段的网格视图中显示卡片,当点击卡片时DetailActivtiy开始。 我正在从Fragments开始详细活动,但是当我尝试在Intent开始详细活动中添加一些额外内容时,我得到NullPointerException。我试图调试代码,但我无法找到问题所在。

这是我的代码:

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 个答案:

答案 0 :(得分:1)

您不应该使用静态变量来保存RecyclerAdapter中的回调侦听器。这意味着当您希望每个RecyclerAdapter拥有自己的回调侦听器时,它们将始终具有相同的回调侦听器。

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

RatedFragment然后没有添加您正在寻找导致NullPointerException的额外内容。

要解决此问题,请从RecyclerAdapter

中删除mListener中的静电
private OnClick mListener;

然后从ViewHolder类的定义中删除静态,使其成为内部类,并可以直接访问监听器:

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

完成此操作后,您仍然需要修复RatedFragment,因为它会显示相同的DetailsFragment而没有您当前需要的额外费用。