Search code examples
androidandroid-arrayadapter

Custom adapter does not clear() (should I @Override?)


I'm quite new to Android dev and I'm not the kind of guy asking questions (this is actually my first ever) without some in-depth research first, but here I'm stuck...

I created a custom adapter to fill a gridview and everything works fine with fake data. But when it comes to clearing the data, there is a problem. My log says it is caused by "java.lang.UsupportedOperationException"

If I simplify my code, here is something which does not work:

    package be.julot.popularmovies;

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;


public class PosterGridFragment extends Fragment {

    private MoviePosterItemAdapter moviePosterAdapter;

    public PosterGridFragment() {}

    MoviePosterItem[] moviePosterItems = {
            new MoviePosterItem("Test movie", "7.6", R.drawable.test),
            new MoviePosterItem("Dude, where is my car?", "2.2", R.drawable.test),
            new MoviePosterItem("Yoooo", "7.2", R.drawable.test),
            new MoviePosterItem("Ulysse is here", "5.4", R.drawable.test),
            new MoviePosterItem("Come on baby", "7.9", R.drawable.test),
            new MoviePosterItem("Limit title to 30 chars please", "5.3", R.drawable.test),
            new MoviePosterItem("Doesn't he?", "9.1", R.drawable.test),
            new MoviePosterItem("Internetar", "2.4", R.drawable.test)
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

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

        moviePosterAdapter = new MoviePosterItemAdapter(getActivity(), Arrays.asList(moviePosterItems));

        GridView posterGrid = (GridView) rootView.findViewById(R.id.movie_grid);
        posterGrid.setAdapter(moviePosterAdapter);

        moviePosterAdapter.clear();

        return rootView;
    }

Problem occurs at the moviePosterAdapter.clear(); Normally, I call that clear() method elsewhere (in onPostExecute of an ASyncTask), but the problem is the same.

My custom adapter extends ArrayAdapter as follows:

package be.julot.popularmovies;


import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class MoviePosterItemAdapter extends ArrayAdapter<MoviePosterItem> {

    private final String LOG_TAG = MoviePosterItemAdapter.class.getSimpleName();

    public MoviePosterItemAdapter(Activity context, List<MoviePosterItem> moviePosterItems) {
        super(context, 0, moviePosterItems);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent){

        MoviePosterItem moviePosterItem = getItem(position);

        if (view == null) {
            view = LayoutInflater.from(getContext()).inflate(R.layout.movies_grid_item, parent, false);
        }

        ImageView posterImage = (ImageView) view.findViewById(R.id.posterImage);
        posterImage.setImageResource(moviePosterItem.moviePoster);

        TextView movieTitle = (TextView) view.findViewById(R.id.movie_title);
        movieTitle.setText(moviePosterItem.movieTitle);

        return view;
    }


}

Should I override the clear() method in my custom adapter class? I have had a look at the original method, but I can't see what to do.

And this is my class for the custom item:

package be.julot.popularmovies;

//Defines each item in the movie poster grid. Each item shows a title, the average of votes and the
//movie poster in background. See movies_grid_item.xml

import java.util.ArrayList;

public class MoviePosterItem {
    String movieTitle;
    String movieAverageVote;
    int moviePoster;

    public MoviePosterItem(String mTitle, String mAverageVote, int mPoster) {
        this.movieTitle = mTitle;
        this.movieAverageVote = mAverageVote;
        this.moviePoster = mPoster;
    }

}

Thanks a lot for any answer you might have or any clue on how to find it by myself! I have seen similar posts but could not find out what was wrong in my code.


Solution

  • Your Android code is fine, the Java array manipulation technique is at fault here. You pass a Arrays.asList() to your adapter - this method returns a fix size array, so you can not remove or add elements to it. This gets stored all the way into the ArrayAdapter (in mObjects) and when you call clear on it you have the nice exception about trying to do something you're not supposed to.

    So it's either:

    1. moviePosterAdapter = new MoviePosterItemAdapter(getActivity(), new ArrayList<>(Arrays.asList(moviePosterItems)));

    or

    1. construct your original array as a regular ArrayList (new ArrayList<>() + add(new MoviePosterItem()) * N)