简体   繁体   中英

I have a gridview in my main activity but the app crashes when i tap an image of the grid after device orientation is changed

The app crashes only if the device orientation is changed. Here is the main activity:

public class MainActivity extends AppCompatActivity implements Listener {

    boolean mTwoPane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (findViewById(R.id.fragment_two) != null) {
            mTwoPane = true;

        } else {
            mTwoPane = false;
        }

        if (null == savedInstanceState) {
            MoviesFragment moviesFragment = new MoviesFragment();
            moviesFragment.setListener(this);
            getSupportFragmentManager().beginTransaction().add(R.id.fragment_movies, moviesFragment).commit();
        }
    }

    @Override
    public void setSelectedMovie(MoviesData.ResultsBean movie) {

        if (mTwoPane == true) {
            DetailFragment detailsFragment = new DetailFragment();
            Bundle extras = new Bundle();
            extras.putSerializable("MoviesData", movie);
            detailsFragment.setArguments(extras);

            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_two, detailsFragment).commit();

        } else {

            Intent intent = new Intent(this, DetailActivity.class);
            intent.putExtra("MoviesData", movie);
            startActivity(intent);

        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.sort_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        if (id == R.id.action_settings) {
            startActivity(new Intent(this, SettingsActivity.class));
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

The main Fragment code:

public class MoviesFragment extends Fragment {

    ArrayList<MoviesData.ResultsBean> moviesList;
    private ImagesAdapter moviesAdapter;
    private ArrayList<String> mImageUrlList;
    Listener mListener;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_movies, container, false);

        mImageUrlList = new ArrayList<String>();

        moviesAdapter = new ImagesAdapter(getActivity(), mImageUrlList);
        GridView list = (GridView) rootView.findViewById(R.id.gridview_movies);
        list.setAdapter(moviesAdapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                Toast.makeText(getActivity(), "title: " + moviesList.get(position).getOriginal_title(), Toast.LENGTH_SHORT).show();

                mListener.setSelectedMovie(moviesList.get(position));
            }
        });

        return rootView;

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

    }

    public void updateMoviesDisplay() {
        FetchMoviesTask fetchMoviesTask = new FetchMoviesTask();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String type = prefs.getString(getString(R.string.pref_display_type_key),
                getString(R.string.pref_display_categeory_defualt));
        String pop = "popular";

        //String displayType="popular?";
        Log.i("type00", type);
        System.out.println("type= " + type);
        if (type.equals("favourite")) {
            System.out.println("type= " + type);
            mImageUrlList.clear();
            MovieDb db = new MovieDb(getActivity());
            moviesList = db.getAllMovie();
            List<MoviesData.ResultsBean> mResultsBean;
            mResultsBean = db.getAllMovie();
            for (int i = 0; i < mResultsBean.size(); i++) {
                mImageUrlList.add(mResultsBean.get(i).getPoster_path());

            }

            moviesAdapter.notifyDataSetChanged();
        } else if (type.equals("popular")) {
            fetchMoviesTask.execute("popular");
        } else if (type.equals("top_rated")) {
            fetchMoviesTask.execute("top_rated");
        }
        Log.i("kkkk", String.valueOf(type.equals(pop)));

    }

    public boolean onOptionsItemSelected(MenuItem item) {


        /* FetchMoviesTask task = new FetchMoviesTask();
        if (id == R.id.popular) {
            task.execute("popular");
            return true;
        } else if (id == R.id.top_rated) {
            task.execute("top_rated");
            return true;
        } else if (id == R.id.favourite_sort) {
            mImageUrlList.clear();
            MovieDb db = new MovieDb(getActivity());
            moviesList = db.getAllMovie();
            List<MoviesData.ResultsBean> mResultsBean;
            mResultsBean = db.getAllMovie();
            for (int i = 0; i < mResultsBean.size(); i++) {
                mImageUrlList.add(mResultsBean.get(i).getPoster_path());

            }
            moviesAdapter.notifyDataSetChanged();
        }
        moviesAdapter.notifyDataSetChanged();*/
        return true;
    }

    public void setListener(Listener listener) {
        this.mListener = listener;
    }

    public static String BuildImageUrl(String imagePath) {
        Uri uri = Uri.parse("http://image.tmdb.org/t/p/").buildUpon().appendEncodedPath("w342").appendEncodedPath(imagePath).build();
        return uri.toString();
    }

    public class FetchMoviesTask extends AsyncTask<String, Void, MoviesData> {

        @Override
        protected MoviesData doInBackground(String... params) {

            try {
                return new FetchMovies().fetchMovieData(params[0], 1 + "");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(MoviesData movie) {
            super.onPostExecute(movie);
            if (movie == null) {
                Toast toast = Toast.makeText(getActivity(), "No internet connection", Toast.LENGTH_LONG);
                toast.show();
                return;
            }

            moviesList = movie.getResults();

            mImageUrlList.clear();
            for (ResultsBean bean : movie.getResults()) {

                mImageUrlList.add(BuildImageUrl(bean.getPoster_path()));

            }

            moviesAdapter.notifyDataSetChanged();

        }
    }

    @Override
    public void onStart() {
        super.onStart();

        updateMoviesDisplay();
    }

}

I get a nullpointerexception:

Attempt to invoke interface method 'void
com.example.mohamed.movieapp.Listener.setSelectedMovie(com.example.mohamed.movieapp.Data.MoviesData$ResultsBean)' on a null object reference at com.example.mohamed.movieapp.MoviesFragment$1.onItemClick in this line in "MoviesFragment" mListener.setSelectedMovie(moviesList.get(position)); in the setOnItemClickListener method

When you rotate the device the savedInstanceState is NOT null. In your activity you ONLY set listener if the savedInstanceState is null. Therefore in the case of device rotation the mListener object in your fragment is NULL. Therefore invoking anything on it will produce NPI.

You need to find fragment by tag or id using SupportFragmentManager in case the savedInstanceState is NOT null, like in case of any configuration change, like, say, device rotation, and in that case set the Listener to a fragment object you find.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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