Search code examples
javaandroidandroid-activityinternal-storage

Retaining ListView data after leaving Android acitivity


I am new to Android Studio. I am trying to use a ListView where the user can add items to a list. But when the user changes or closes the activity I want the items to come back as they were the last time the user saw them. I am not too familiar with the activity LifeCycle and how to use it yet so any resource or help is appreciated. Thanks. Here is my code:

package com.example.listviewtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity<i> extends AppCompatActivity {
    private List nameArr;
    private String textToAdd;
    //input textbox
    private EditText stuff;


    // Add player names and scores to the list
    private ListView score_lv;
    //Append
    private ArrayAdapter<String> arrayAdapter1;


    //Clear Scores button
    private Button updateButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        nameArr = new ArrayList<Object>();
        stuff  = (EditText)findViewById(R.id.editText);
        score_lv  = (ListView) findViewById(R.id.theList);
        arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);

        updateButton  = (Button) findViewById(R.id.addButton);
        updateButton.setOnClickListener(
                new Button.OnClickListener() {
                    public void onClick(View v) {
                        nameArr.add(stuff.getText().toString());
                        //get data from other activity
                        textToAdd = getIntent().getExtras().getString("textData");
                        score_lv.setAdapter(arrayAdapter1);
                    }
                });

        final Button nextAct = (Button) findViewById(R.id.toNext);
        nextAct.setOnClickListener(
                new Button.OnClickListener() {
                    public void onClick(View v) {
                        Intent j = new Intent(MainActivity.this, Main2Activity.class);
                        startActivity(j);
                    }
                }
        );
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

Edit:

I was able to get the List updated using FileInputStream and FileOutputStream (I am trying to write to the Internal Storage). Because this app has 2 activites, when I switch to the other activity and go back to this one, the List and all its items remain. However, when I close the app entirely and then reopen the app, it seems that all the items in the list disappear. How do I make it stay using the FileI/OStreams (I know there is other methods like SQLite and such but I am trying to challenge myself by using other methods). Here is my updated code so far (thanks again to all for all of your help):

package com.example.listviewtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class MainActivity<i> extends AppCompatActivity {
    private static final List nameArr = new ArrayList<Object>();
    //input textbox
    private EditText stuff;


    // Add player names and scores to the list
    private ListView score_lv;
    //Append
    private ArrayAdapter<String> arrayAdapter1;

    //Clear Scores button
    private Button updateButton;

    private static final String fileName = "scores";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        stuff  = (EditText)findViewById(R.id.editText);
        score_lv  = (ListView) findViewById(R.id.theList);
        arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);

        score_lv.setAdapter(arrayAdapter1);

        //button to update the ListView
        updateButton  = (Button) findViewById(R.id.addButton);
        updateButton.setOnClickListener(
                new Button.OnClickListener() {
                    public void onClick(View v) {
                        //write data to the internal phone app File
                        try{
                            FileOutputStream fileOS = openFileOutput("scores", MODE_PRIVATE);
                            OutputStreamWriter osw = new OutputStreamWriter(fileOS);
                            try{
                                osw.write(stuff.getText().toString());
                                osw.flush();
                                osw.close();
                                Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
                            }catch(IOException e){
                                e.printStackTrace();
                            }
                        }catch (FileNotFoundException e){
                            e.printStackTrace();
                        }

                        //read data from Saved File to update the ListView
                        nameArr.add(readFile("scores"));
                        score_lv.setAdapter(arrayAdapter1);
                    }
                });

        //button to go to the next Activity
        final Button nextAct = (Button) findViewById(R.id.toNext);
        nextAct.setOnClickListener(
                new Button.OnClickListener() {
                    public void onClick(View v) {
                        Intent j = new Intent(MainActivity.this, Main2Activity.class);
                        startActivity(j);
                    }
                }
        );
    }

    //as soon as this Activity starts, we read from the Output File
    public String readFile(String file){
        StringBuilder text = new StringBuilder();
        try{
            FileInputStream fis = openFileInput(file);
            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
            String line;

            while((line = reader.readLine()) != null){
                text.append(line);
            }
            reader.close();
        }catch(Exception e){
            e.printStackTrace();
            Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
        }
        return text.toString();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


}

Solution

  • So I added a Clear button but I was able to save multiple lines in the "scores" file that I saved in the internal device storage. When I close the app or go to the other activity and go back to this MainActivity with the ListView the information remains (because it reads directly from the "scores" file). The only thing is that it updates the 1 and only ListView item. I used nameArr.clear(); to clear the ListView everytime and the nameArr.clear(); and text.append('\n'); to read and write to the file so that each Text Input by the User appears the way I want them to (as a list). So here is my final code:

    public class MainActivity<i> extends AppCompatActivity {
        private static final List nameArr = new ArrayList<Object>();
        //input textbox
        private EditText stuff;
    
    
        // Add player names and scores to the list
        private ListView score_lv;
        //Append
        private ArrayAdapter<String> arrayAdapter1;
    
        //Clear Scores button
        private Button updateButton;
    
        private static final String fileName = "scores";
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            stuff  = (EditText)findViewById(R.id.editText);
            score_lv  = (ListView) findViewById(R.id.theList);
            arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameArr);
    
            nameArr.clear();
            nameArr.add(readFile(fileName));
            score_lv.setAdapter(arrayAdapter1);
    
            //button to update the ListView
            updateButton  = (Button) findViewById(R.id.addButton);
            updateButton.setOnClickListener(
                    new Button.OnClickListener() {
                        public void onClick(View v) {
                                                    //write data to the internal phone app File
                            try{
                                FileOutputStream fileOS = openFileOutput(fileName, MODE_APPEND);
                                OutputStreamWriter osw = new OutputStreamWriter(fileOS);
                                try{
                                    osw.write("\n");
                                    osw.write(stuff.getText().toString());
                                    osw.flush();
                                    osw.close();
                                    Toast.makeText(getBaseContext(),"Scores Saved to "+getFilesDir() + "/", Toast.LENGTH_LONG).show();
                                }catch(IOException e){
                                    e.printStackTrace();
                                }
                            }catch (FileNotFoundException e){
                                e.printStackTrace();
                            }
    
    
                            //read data from Saved File to update the ListView with ALL items from the file
                            nameArr.clear();
                            nameArr.add(readFile(fileName));
                            score_lv.setAdapter(arrayAdapter1);
                        }
                    });
    
            //button to go to the next Activity
            final Button nextAct = (Button) findViewById(R.id.toNext);
            nextAct.setOnClickListener(
                    new Button.OnClickListener() {
                        public void onClick(View v) {
                            Intent j = new Intent(MainActivity.this, Main2Activity.class);
                            startActivity(j);
                        }
                    }
            );
    
            //delete file and clear ListView button
            final Button clearB = (Button) findViewById(R.id.clearButton);
            clearB.setOnClickListener(
                    new Button.OnClickListener() {
                        public void onClick(View v) {
                            deleteFile(fileName);
                            Toast.makeText(getBaseContext(), "List Cleared", Toast.LENGTH_LONG).show();
                            //clear list
                            score_lv.setAdapter(null);
                        }
                    }
            );
        }
    
        //as soon as this Activity starts, we read from the Output File
        public String readFile(String file){
            StringBuilder text = new StringBuilder();
            try{
                FileInputStream fis = openFileInput(file);
                BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
                String line;
    
                while((line = reader.readLine()) != null){
                    text.append(line);
                    text.append('\n');
                }
                reader.close();
            }catch(Exception e){
                e.printStackTrace();
                Toast.makeText(MainActivity.this,"Error reading file!",Toast.LENGTH_LONG).show();
            }
            return text.toString();
        }