从水平旋转到垂直旋转时崩溃

时间:2016-06-16 14:49:05

标签: android android-fragments

我正在为横向模式和纵向模式使用两种不同的布局。

经过几个小时后,我无法找出问题所在。 该应用程序在垂直启动时工作正常,并且在水平旋转时也能正常工作。

当我从水平位置向后旋转到垂直位置并从列表中选择一个项目时,应用程序崩溃。

06-16 14:23:33.769 16108-16108/in.udacity.gagan.cinephilia E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.udacity.gagan.cinephilia, PID: 16108
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.design.widget.CollapsingToolbarLayout.setTitle(java.lang.CharSequence)' on a null object reference
at in.udacity.gagan.cinephilia.DetailActivityFragment$3.onResponse(DetailActivityFragment.java:165)
at in.udacity.gagan.cinephilia.DetailActivityFragment$3.onResponse(DetailActivityFragment.java:148)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
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)

主要活动回调功能

@Override
public void onItemSelected(String id,
    String backDrop,
    String title,
    int darkColor,
    int lightColor) {

DetailActivityFragment displayFrag = (DetailActivityFragment) getSupportFragmentManager()
                       .findFragmentById(R.id.fragment_left);
    if (displayFrag == null) {
        Intent mIntent = new Intent(MainActivity.this, DetailActivity.class);
                mIntent.putExtra("id", id);
                mIntent.putExtra("backdrop_path", backDrop);
                mIntent.putExtra("title", title);
                mIntent.putExtra("darkColor", darkColor);
                mIntent.putExtra("lightColor", lightColor);
                startActivity(mIntent);
       }
       else 
            displayFrag.getContent(id, lightColor);}

详情活动片段功能

public void getContent(String id, int lightColor) {
        fetchMovieDetails(id, lightColor);
    }

FetchMovieDetails功能

private void fetchMovieDetails(final String id, final int color){

    mMovieDetail = null;
    mDetailsList.clear();
    String url = TmdbUrls.MOVIE_URL + id + "?" + BuildConfig.THE_MOVIE_DATABASE_API_KEY;
    String reviewURL = TmdbUrls.MOVIE_URL + id + TmdbUrls.REVIEW + "?" + BuildConfig.THE_MOVIE_DATABASE_API_KEY;
    Log.e("TAG", url);

    JsonObjectRequest getDetails = new JsonObjectRequest(url,null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                String imageUrl = "http://image.tmdb.org/t/p/w780/" + response.getString("backdrop_path");
                String iconImageURL="http://image.tmdb.org/t/p/w342/" + response.getString("poster_path");

                String genres = "";
                JSONArray genreArray = response.getJSONArray("genres");

                for (int i = 0; i < genreArray.length(); i++) {
                    String genre = genreArray.getJSONObject(i).getString("name");
                    if (i != genreArray.length() - 1)
                        genres += genre + ", ";
                    else
                        genres += genre + ".";
                }
                mCollapsingToolbarLayout.setTitle(response.getString("title"));
                mMovieDetail = new MovieDetail(id,
                        response.getString("title"),
                        response.getString("vote_average"),
                        genres,
                        response.getString("release_date"),
                        response.getString("status"),
                        response.getString("overview"),
                        iconImageURL,
                        imageUrl,
                        response.getString("tagline"),
                        response.getString("original_language"),
                        response.getString("runtime"),
                        response.getString("popularity"),
                        response.getString("vote_count")
                );
                Glide.with(getActivity())
                        .load(imageUrl)
                        .centerCrop()
                        .crossFade()
                        .diskCacheStrategy(DiskCacheStrategy.RESULT)
                        .into(mImageView);
                //fab.setBackgroundTintList(ColorStateList.valueOf(lightColor));
                mDetailsList.add(mMovieDetail);
                mAdapter = new DetailsAdapter(color, mDetailsList, mReviewList, mTrailersList, getActivity());
                mRecyclerView.setAdapter(mAdapter);

                boolean isMovieInDB = ContentProviderHelperMethods
                        .isMovieInDatabase(getActivity(),
                                String.valueOf(mMovieDetail.getId()));
                if (isMovieInDB) {
                    fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_like));
                } else {
                    fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_like_outline));
                }

                fab.show();
                fab.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        boolean isMovieInDB = ContentProviderHelperMethods
                                .isMovieInDatabase(getActivity(),
                                        String.valueOf(mMovieDetail.getId()));
                        if (isMovieInDB) {
                            Uri contentUri = MoviesContentProvider.CONTENT_URI;
                            getActivity().getContentResolver().delete(contentUri, "id=?", new String[]{String.valueOf(mMovieDetail.getId())});
                            Snackbar.make(view, getResources().getString(R.string.removed_from_favourites), Snackbar.LENGTH_LONG)
                                    .setAction("Action", null).show();
                            fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_like_outline));

                        } else {
                            ContentValues values = new ContentValues();
                            values.put(DatabaseHelper.KEY_ID, mMovieDetail.getId());
                            values.put(DatabaseHelper.KEY_TITLE, mMovieDetail.getTitle());
                            values.put(DatabaseHelper.KEY_RATING, mMovieDetail.getVote_average());
                            values.put(DatabaseHelper.KEY_GENRE, mMovieDetail.getGenre());
                            values.put(DatabaseHelper.KEY_DATE, mMovieDetail.getReleasedate());
                            values.put(DatabaseHelper.KEY_STATUS, mMovieDetail.getStatus());
                            values.put(DatabaseHelper.KEY_OVERVIEW, mMovieDetail.getOverview());
                            values.put(DatabaseHelper.KEY_BACKDROP, mMovieDetail.getBackdrop_path());
                            values.put(DatabaseHelper.KEY_VOTE_COUNT, mMovieDetail.getmVotecount());
                            values.put(DatabaseHelper.KEY_TAG_LINE, mMovieDetail.getmTagline());
                            values.put(DatabaseHelper.KEY_RUN_TIME, mMovieDetail.getmRuntime());
                            values.put(DatabaseHelper.KEY_LANGUAGE, mMovieDetail.getmLanguage());
                            values.put(DatabaseHelper.KEY_POPULARITY, mMovieDetail.getmPopularity());
                            values.put(DatabaseHelper.KEY_POSTER, mMovieDetail.getPoster_path());

                            getActivity().getContentResolver().insert(MoviesContentProvider.CONTENT_URI, values);

                            Snackbar.make(view, getResources().getString(R.string.added_to_favourites), Snackbar.LENGTH_LONG)
                                    .setAction("Action", null).show();

                            fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_like));
                        }
                    }
                });
                fetchTrailerData(id);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            showSnackBar(getString(R.string.error_msg));
        }
    });
    NetworkController.getInstance().addToRequestQueue(getDetails);
}

DetailActivityFragment onCreateView

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    View rootView= inflater.inflate(R.layout.fragment_detail, container, false);
    mCollapsingToolbarLayout = (CollapsingToolbarLayout) rootView.findViewById(R.id.collapsing_toolbar_layout_movie_details);

    lightColor = getActivity().getIntent().getIntExtra("lightColor", 0);
    id = getActivity().getIntent().getStringExtra("id");

    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());


    mToolbar = (Toolbar) rootView.findViewById(R.id.toolbar_movie_details);

    mCollapsingToolbarLayout.setBackgroundColor(lightColor);
    mCollapsingToolbarLayout.setContentScrimColor(lightColor);
    mCollapsingToolbarLayout.setExpandedTitleColor(ContextCompat.getColor(getActivity(), android.R.color.transparent));
    mCollapsingToolbarLayout.setCollapsedTitleTextColor(ContextCompat.getColor(getActivity(), android.R.color.white));

    mImageView = (ImageView) rootView.findViewById(R.id.backdrop);
    fab = (FloatingActionButton) rootView.findViewById(R.id.fab);
    /*fab.setBackgroundTintList(ColorStateList.valueOf(lightColor));*/

    mToolbar.setNavigationIcon(ContextCompat.getDrawable(getActivity(), R.drawable.ic_back));
    mToolbar.inflateMenu(R.menu.menu_detail);
    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getActivity().finish();
        }
    });
    mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {

            if (item.getItemId() == R.id.action_share) {
                startActivity(Intent.createChooser(shareIntent(title), getResources().getString(R.string.share)));
                return true;
            }
            return true;
        }
    });
    fetchMovieDetails(id ,lightColor);
    return rootView;
}

2 个答案:

答案 0 :(得分:0)

你真正的问题是你打电话来获取你的信息displayFrag.getContent(id, lightColor);因为看起来你的片段内容可能会改变我不会使用静态片段(在你的布局xml中声明)并手动添加/替换单击项目时的片段,并在setArguments()方法

中发送片段需要加载的信息

这样,当您的设备旋转时,您仍然可以获得信息,并且在onCreateView中,您只需拨打getContent(id, lightColor)即可获得这些错误(但我仍会检查您的任何视图是否为空在你尝试使用它们之前

答案 1 :(得分:-1)

在DetailActivityFragment.java第165或148行

if(mCollapsingToolbarLayout == null) {
   mCollapsingToolbarLayout = (CollapsingToolbarLayout) rootView.findViewById(R.id.collapsing_toolbar_layout_movie_details);
 } mCollapsingToolbarLayout.setTitle("...")

添加

android:configChanges="orientation|screenSize"
清单中的

第二种方法可能不是满足您需求的最佳解决方案...... https://developer.android.com/guide/topics/resources/runtime-changes.html

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

      if(mCollapsingToolbarLayout == null) {
          mCollapsingToolbarLayout = (CollapsingToolbarLayout) 
          getActivity().findViewById(R.id.collapsing_toolbar_layout_movie_details);
    } mCollapsingToolbarLayout.setTitle("...")
 }