Razgriz
Razgriz

Reputation: 7343

Updating a List View

I've been stuck with this for a long while and it's really frustrating. Basically the app starts off with a ListView containing Movie Titles, their Gross, and Year.

The user then can add a new movie, gross, and year using a different activity from the menu. The values are then returned back to the first activity and is placed at the bottom of the list.

This is where my problem begins. The first problem I had is that the app Force Closes when it's about to display the new item. Now, it doesn't want to display at all. Here's the Code:

public class Lab7_084106 extends ListActivity {

private SampleCustomAdapter adapter;
private ArrayList<MyMovies> movieList;

public static boolean Flag = false;

@SuppressWarnings("null")
@Override
public void onCreate(Bundle savedInstanceState) {

    //create stuff
    super.onCreate(savedInstanceState);
    movieList = new ArrayList<MyMovies>();



    Intent data = getIntent();
    //Flag = data.getStringExtra("Flag");

    String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
    String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
    String[] oldYearList = getResources().getStringArray(R.array.yearArray);


    //if there's no new movie to display
    if(!Flag){                  

        for (int i = 0; i < oldMovieList.length; i++) {
            MyMovies newMovie = new MyMovies();
            newMovie.setMovie(oldMovieList[i] + "NEW");
            newMovie.setGross(oldGrossList[i]);
            newMovie.setYear(oldYearList[i]);
            movieList.add(newMovie);
        }

        //adapter = new SampleCustomAdapter(movieList);

        //setContentView(R.layout.row);
        //setListAdapter(adapter);
    }
    else{

        Toast.makeText(getApplicationContext(), "Else Entered", Toast.LENGTH_SHORT).show();

        int newLength = 50; //oldMovieList.length + 1;

        //create new array to store the new value

        String[] newMovieArray = new String[newLength];
        String[] newGrossArray = new String[newLength];
        String[] newYearArray = new String[newLength];

        //populate the new list with the old one plus the new one
        for (int i = 0; i < newLength; i++) {

            if( i != newLength - 1){
                newMovieArray[i] = oldMovieList[i];
                newGrossArray[i] = oldGrossList[i];
                newYearArray[i] = oldYearList[i];       
            }
            else{
                newMovieArray[i] = data.getStringExtra("Title");
                newGrossArray[i] = data.getStringExtra("Gross");
                newYearArray[i] = data.getStringExtra("Year");
            }

        }

        //populate the old one using the new list
        for (int i = 0; i < newLength; i++) {

            oldMovieList[i] = newMovieArray[i];
            oldGrossList[i] = newGrossArray[i];
            oldYearList[i] = newYearArray[i];

        }

        //display stuff
        for (int i = 0; i < newLength; i++) {

                MyMovies newMovie = new MyMovies();
                newMovie.setMovie(oldMovieList[i]);
                newMovie.setGross(oldGrossList[i]);
                newMovie.setYear(oldYearList[i]);
                movieList.add(newMovie);

        }

        //adapter = new SampleCustomAdapter(movieList);
        //setListAdapter(adapter);

    }

    adapter = new SampleCustomAdapter(movieList);
    setListAdapter(adapter);


    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    //set stuff such that Page2 sends back a result to page 1
    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView t = (TextView) view.findViewById(R.id.title);
            String name = (String) t.getText();
            Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();

        }
    });
}


private class SampleCustomAdapter extends BaseAdapter {

    private ArrayList<MyMovies> internalList;

    String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
    String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
    String[] oldYearList = getResources().getStringArray(R.array.yearArray);


    private ArrayList<MyMovies> GetSearchResults(){
        ArrayList<MyMovies> results = new ArrayList<MyMovies>();
        // make sure the arrays have the same length
        for (int i = 0; i < oldMovieList.length; i++) {
            MyMovies sr = new MyMovies();
            sr.setMovie(oldMovieList[i]);
            sr.setGross(oldGrossList[i]);
            sr.setYear(oldYearList[i]);
            results.add(sr);

       }
       return results;

    }

    public SampleCustomAdapter(ArrayList<MyMovies> contacts){
        internalList = contacts;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return internalList.size();
    }

    @Override
    public Object getItem(int index) {
        // TODO Auto-generated method stub
        return internalList.get(index);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // NOTE: you can only do this if you have access to the Activity object
        //       which is why this is an inner class
        LayoutInflater inflater = getLayoutInflater();
        View view;

        //System.out.println(parent.getClass().getName());
        //System.out.println(position);


        if (convertView==null){
            view = inflater.inflate(R.layout.row, null);
        }
        else{
            view = convertView;
        }

        // extract the views to be populated
        TextView movie = (TextView) view.findViewById(R.id.title);
        TextView gross = (TextView) view.findViewById(R.id.gross);
        TextView date = (TextView) view.findViewById(R.id.date);

        // extract the object that will fill these

        MyMovies movies = GetSearchResults().get(position);
        //MyMovies movies = internalList.get(position);


        movie.setText(movies.getMovie());
        gross.setText(movies.getGross());
        date.setText(movies.getYear());


        // return the view
        return view;
    }
}


//menu lawl
@Override
public boolean onCreateOptionsMenu(Menu menu){
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menupage1, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    //Handle item selection using item.getItemId()
    switch(item.getItemId()){
    case R.id.addMovie:
        AddMovie();
        break;
    }


     return true;
}
//end menu stuff lol

public void AddMovie(){
    Intent intent2 = new Intent(this, com.Android.Lab7.addMovie.class);

    startActivity(intent2);
    finish();
}
 }

The Flag Boolean variable basically tells if the user added a movie. If the user added a movie, it will enter the else statement and update from there. I'm really confused where to put this if-else statement.

I ran a few experiments with the GetSearchResult function of SampleCustomAdapter and found out that it directly affects the output of the ListView. I tried placing the if-else statement there but I ended up with a LOT of items in the ListView.

Using adapter.notifyDataSetChanged(); gives a NullPointerException error and points to where I placed it. So even if do something like:

MyMovies newMovie = new MyMovies();
newMovie.setMovie(data.getStringExtra("Title"));
newMovie.setGross(data.getStringExtra("Gross"));
newMovie.setYear(data.getStringExtra("Year"));
movieList.add(newMovie);
adapter.notifyDataSetChanged();

As the else block, it does not work. I think it has something to do with the fact that I'm getting my initial values from the string.xml resource folder and not via hardcode or user input.

This problem has been frustrating me ever since 2-3 days ago and help is really appreciated. Thanks.

Upvotes: 0

Views: 264

Answers (2)

A. AMAIDI
A. AMAIDI

Reputation: 6849

you just have to notify the data set Changed on your adapter

movieList.add(newMovie);
adapter.notifyDataSetChanged();

the listview will be updated automatically

UPDATE you can always use the following it'll work but I prefer notifying the adapter.

movieList.add(newMovie);
adapter = new SampleCustomAdapter(movieList);
setListAdapter(adapter);

Upvotes: 2

Rushabh Patel
Rushabh Patel

Reputation: 3080

you should use adapter.notifyDataSetChanged(). CheckThis Link

Upvotes: 0

Related Questions