简体   繁体   English

意图putExtra()不起作用

[英]Intent putExtra() not working

Hi in my MainActivity I implemented ViewPager with TabLayout with 3 tabs and each view page starts new Fragment. 嗨,在MainActivity我实现了带有3个标签的ViewPagerTabLayout ,并且每个视图页面都开始了新的Fragment。 I am showing cards in a grid view in each Fragment and when a card is clicked DetailActivtiy starts. 我在每个片段的网格视图中显示卡片,并且单击DetailActivtiy时, DetailActivtiy开始。 I am starting detail activity from Fragments but when I try to put some extra in Intent starting detail activity I get NullPointerException . 我从Fragments开始细节活动,但是当我尝试在Intent开始细节活动中添加一些额外内容时,我得到NullPointerException I tried to debug code but I am unable to find where the problem is. 我尝试调试代码,但是找不到问题所在。

Here's my code: 这是我的代码:

PopularFragment (one of the tab layout in 3 tabs) 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);
}
}

Here onClicked() method is called when any card of RecyclerView is clicked. 单击任何RecyclerView卡时,将调用onClicked()方法。 RecyclerAdapter : 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);
    }
}
}

When I start DetailActivity without putting extra in Intent it works but when I put extra in Intent and try to retrieve it in DetailActivity I get NullPointerException . 当我在没有在Intent额外DetailActivity情况下启动DetailActivity ,它可以工作,但是当我在Intent额外内容并尝试在DetailActivity检索它时,我得到了NullPointerException In DetailFragment (contained by DetailActivity i try to get intent as): 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);
}
}

Here's the Github repo 这是Github回购

Logcat: 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) 

You should not be using a static variable to hold the callback listener in your RecyclerAdapter . 您不应使用静态变量将回调侦听器保存在RecyclerAdapter This means each RecyclerAdapter will always have the same callback listener when you want each one to have its own. 这意味着当您希望每个RecyclerAdapter具有自己的回调侦听器时,它们将始终具有相同的回调侦听器。

That is why you are experiencing this issue. 这就是为什么您遇到此问题的原因。 RatedFragment and PopularFragment are both using a RecyclerAdapter . RatedFragmentPopularFragment都使用RecyclerAdapter When you click an image the callback from your RatedFragment will be called even when viewing the PopulareFragmnet . 当您单击图像时,即使查看PopulareFragmnet也会调用RatedFragment的回调。

RatedFragment is then not adding the extra you are looking for which is causing the NullPointerException . 然后, RatedFragment不会添加您正在寻找的导致NullPointerException的额外内容。

To fix this remove static from mListener in the RecyclerAdapter : 为了解决这个问题,从mListener消除静电的RecyclerAdapter

private OnClick mListener;

Then remove static also from the definition of the ViewHolder class so it becomes an inner class and can access the listener directly: 然后从ViewHolder类的定义中也删除static,使其成为一个内部类并可以直接访问侦听器:

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

After doing this you will still have to fix the RatedFragment since it will show the same DetailsFragment without the extra you are currently requiring. 完成此操作后,您仍将必须修复RatedFragment因为它将显示相同的DetailsFragment而没有您当前需要的额外信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM