0

I have Arraylist(mNamelist) in ActivityPlayers. It's been declared as public static so I can access it in ActivityNewGame. My problem is that when I launch my app and go straight to that ActivityNewGame, it won't render that arraylist, before I have visited ActivityPlayers (I have to literally just open it), after that it renders that list in ActivityNewGame perfectly fine within that whole session before I again shut down the app. Any ideas why this is, or what could I do? This app is my own project and it has nothing sensitive data so "uglier" solutions are also fine, as long as it won't show to the user.

Here is my ActivityPlayers, addItem() insert and save new name to the list

public class ActivityPlayers extends AppCompatActivity {
    public static ArrayList<NameItem> mNameList;

    private RecyclerView mRecyclerViewPlayers;
    private NameAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    private Button buttonAdd;
    private EditText textAdd;

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

        loadData();
        buildRecyclerView();
        setButtons();
    }

    private void saveData() {
        /** save data to shared pref **/
        SharedPreferences prefs = getSharedPreferences("shared preference", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        try {
            editor.putString("SharedPrefKey", ObjectSerializer.serialize(mNameList));
        } catch (IOException e) {
            e.printStackTrace();
        }
        editor.commit();
    }

    private void loadData() {
        if (mNameList == null) {
            mNameList = new ArrayList<>();
        }

        SharedPreferences prefs = getSharedPreferences("shared preference", Context.MODE_PRIVATE);
        try {
            mNameList = (ArrayList<NameItem>) ObjectSerializer.deserialize(prefs.getString("SharedPrefKey", ObjectSerializer.serialize(new ArrayList<NameItem>())));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void addItem(int position) {
        /** Get user input (name) **/
        textAdd = findViewById(R.id.name_input);

        /** Add name to the list **/
        mNameList.add(position, new NameItem(textAdd.getText().toString().trim()));

        /** sort that list **/
        sortArrayList();

        /** Save to shared pref **/
        saveData();

        /** Show changed list to user **/
        mAdapter.notifyItemInserted(position);

        /** Clear the input field **/
        textAdd.getText().clear();
    }

And here is my ActivityNewGame, insertNames() takes that Arraylist from ActivityPlayers and insert its names in to the recyclerview items.

public class ActivityNewGame extends AppCompatActivity {
    private ArrayList<NewGamePlayerItem> mPlayerList;

    private RecyclerView mRecyclerView;
    private NewGamePlayerAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

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

        insertNames();
        buildRecyclerView();
    }

    private void insertNames() {
        if (ActivityPlayers.mNameList == null) {
            mPlayerList = new ArrayList<>();
        } else {
            mPlayerList = new ArrayList<>();

            for (int i = 0; i < ActivityPlayers.mNameList.size(); i++) {
                /** false here is for my checkbox, which is in the item **/
                mPlayerList.add(new NewGamePlayerItem(false, ActivityPlayers.mNameList.get(i).getText1()));
            }
        }
    }
Antti
  • 89
  • 1
  • 5

2 Answers2

0

This is Due to the mNamelist in ActivityPlayers is empty

Data pass in the mNamelist is in the ActivityNewGame So you have to pass the data from the ActivityNewGame in order to render the arrayList

This is my suggestion without seeing the code. But I think this works for you and you might understand.

Sagar Khurana
  • 184
  • 1
  • 2
  • 11
0

You're basically not initializing your mNameList until the ActivityPlayer is opened. All you need to do is initialize the values in ActivityNewGame.

Change your loadData() into a static function and call it first in your onCreate() in ActivityNewGame.

Edit -

    public void loadData(Context context) {
        if (mNameList == null) {
            mNameList = new ArrayList<>();
        }

        //SharedPreferences prefs = getApplicationContext().getSharedPreferences("shared preference", Context.MODE_PRIVATE);
        SharedPreferences prefs = context.getSharedPreferences("shared preference", Context.MODE_PRIVATE);
        try {
            mNameList = (ArrayList<NameItem>) ObjectSerializer.deserialize(prefs.getString("SharedPrefKey", ObjectSerializer.serialize(new ArrayList<NameItem>())));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

Just call loadData(this) in the onCreate as necessary.

Chrisvin Jem
  • 3,940
  • 1
  • 8
  • 24
  • I made it static void loadData(), but now it gives this error: SharedPreferences prefs = getSharedPreferences("shared preference", Context.MODE_PRIVATE); "getSharedPreferences" ---> non-static method cannot be referenced from static context – Antti Jul 14 '19 at 05:44
  • Use `getApplicationContext().getSharedPreferences()` – Chrisvin Jem Jul 14 '19 at 05:48
  • SharedPreferences prefs = getApplicationContext().getSharedPreferences("shared preference", Context.MODE_PRIVATE); still the same. – Antti Jul 14 '19 at 05:50
  • You can create an interface class in ActivityNewGame and implement in on the ActivityPlayer class. – m33ts4k0z Jul 14 '19 at 05:53
  • You could try passing your activity context to the `loadData` method and use that context to call `getSharedPreferences`. Even application Context should work. – Chrisvin Jem Jul 14 '19 at 05:54
  • using this.getSharedPreferences will also work. The shared preferences are the same across the activities. Actually you dont need to call loadData at all. You can get the preferences from any activity in your app. – m33ts4k0z Jul 14 '19 at 05:58
  • `this` can't be accessed in static methods, `this` basically refers to the activity object. – Chrisvin Jem Jul 14 '19 at 06:00
  • Anyhow, here's a [SO link](https://stackoverflow.com/a/3806085/11016588) that'll hopefully solve your SharedPreferences issue. – Chrisvin Jem Jul 14 '19 at 06:02
  • Oh ok. It works using kotlin. Kotlins compiler determines automatically the reference of this and there are no static methods in kotlin. – m33ts4k0z Jul 14 '19 at 06:04
  • @ChrisvinJem how do I pass activity context? – Antti Jul 14 '19 at 06:04
  • @Antti check the SO link I posted in my previous comment. – Chrisvin Jem Jul 14 '19 at 06:06
  • @m33ts4k0z You can create static functions in Kotlin by using `@JvmStatic` annotation in methods in the companion object. `this` won't work in those methods. (P.S- Dude, your name's so hard to spell on the phone ) – Chrisvin Jem Jul 14 '19 at 06:09
  • @Chrisvim Jem Why would you want to create complexities in your life? Any particulat advantage of using static annotations? (But there is autocomplete for my name after the @ symbol =]. Aparently not on mobile haha) – m33ts4k0z Jul 14 '19 at 06:15
  • @m33ts4k0z Usually for utility classes, where I don't want to create an object. If you don't use the static annotation and just create a pseudo static function in the companion object, then when I call the function in Java classes, I'd have to call it like `utilityClass.companion.staticMethod()`. That's fairly intuitive for Kotlin programmers, but people who have worked purely in Java might not be able to understand and use it intuitively. – Chrisvin Jem Jul 14 '19 at 06:23
  • I didn't fully understand this, so I made: public static SharedPreferences getSharedPreferences (Context ctxt) { return ctxt.getSharedPreferences("shared preference", Context.MODE_PRIVATE); } Should I now call this method in ActivitynewGame instead of loadData()? – Antti Jul 14 '19 at 06:24
  • @Chrisvin Jem Interesting. This is in order to avoid instantiation and as I read, is primarly used to mix code with java. Cool. Thanks for the explanation. – m33ts4k0z Jul 14 '19 at 06:27
  • ActivityPlayers.loadData(this); in ActivityNewGame? – Antti Jul 14 '19 at 06:37