androidarraylistorientationautocompletetextviewandroid-loadermanager

How to save ArrayList data and use in AutoCompleteTextView , after change device orientation


I have tride saveInstanceState and it actually helps to save data but AutoCompleteTextView doesnt see any data (in Log i see the data is exists and they are correct) Then i change orientation second time and in Log see ArrayList = null; here some code

  ...
    public class AddDayActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> 
    ...
    ArrayAdapter<String> adapter;
    private AutoCompleteTextView edit_day_name; 
    private ArrayList<String> autoCompleteList;
    private ArrayList<Integer> autoCompleteListPrice;
    ...
     protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.add_pay_day);
             autoCompleteList = new ArrayList<String>(); //Array list witch need to save 
             autoCompleteListPrice = new ArrayList<Integer>();//Array list witch need to save 

    ...
        edit_day_name = findViewById(R.id.edit_day_name); //AutoCompleteTextView
    ...
    if (savedInstanceState != null) {
            autoCompleteList.addAll(Objects.requireNonNull(savedInstanceState.getStringArrayList("BundleAutoCompleteList")));
            autoCompleteListPrice.addAll(Objects.requireNonNull(savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")));
            Log.d(UtilContract.LOG_KEY, " onRestoreInstanceState Working " + savedInstanceState.getIntegerArrayList("BundleAutoCompleteList")
                    + "\n" +
                    savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")
                    + "\n" + autoCompleteList + "\n" + autoCompleteListPrice);


        } 
            adapter = new ArrayAdapter<String>(this,
                    R.layout.dropdown_menu_popup_item, autoCompleteList);
            Log.d(UtilContract.LOG_KEY, ".." + autoCompleteList);
            edit_day_name.setAdapter(adapter);

        ...
         LoaderManager.getInstance(this).initLoader(NAME_UNIC_LOADER, null, this);
        ...
         @Override
        protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        //Save data in  Bundle
        outState.putStringArrayList("BundleAutoCompleteList", autoCompleteList);
        outState.putIntegerArrayList("BundleAutoCompleteListPrice", autoCompleteListPrice);
        Log.d(UtilContract.LOG_KEY, " savedInstanceState Save " + autoCompleteListPrice + "\n" + autoCompleteList);
    }

Loader to fill an array from SQL DB

 @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
        String[] projection = {
                UtilContract.KEY_ID,
                KEY_NAME_DETAIL,
                KEY_PRICE_OF_DETAIL
        };

        CursorLoader cursorLoader = new CursorLoader(this,
                UtilContract.DetailTable.CONTENT_URI,
                projection,
                null,
                null,
                KEY_NAME_DETAIL
        );
        Log.d(LOG_KEY, " CursorLoader  DetailTable " + cursorLoader);
        return cursorLoader;
    }
      @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
        int count = data.getCount();
        if (autoCompleteList.isEmpty() || autoCompleteListPrice.isEmpty()) {
            //
            while (data.moveToNext()) {
                autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL)));
                autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
            }
        } else {
            //
            autoCompleteList.clear();
            autoCompleteListPrice.clear();
            // 
            while (data.moveToNext()) {
                autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL)));                autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
            }
        }
        Log.d(LOG_KEY, " Cursor  DetailTable " + data + " count " + count);
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {
 adapter.clear();
    }

In this situation how correctly save data for AutoComplateView ?

PS: I use "androidx" and ".material:1.1.0-alpha09" to make from AutoComplateView "ExposedDropdownMenu"


Solution

  • There is too small amount of code to tell for sure, but from what I see the problem may be in Loader implementation and its synchronization with the rest of the code.

    Loaded loads data asynchronously. That means after you've rotated the device your code executed well, but the loader started to load once more. Before the loading actually started it calls onLoaderReset which contains adapter.clear() call. So all the data from adapter disappears thus AutocompleteTextView has nothing to show.

    Also I can see in the onLoadFinished method you retrieve data but you do not set it into adapter - thus the adapter is empty.

    One more time - I am not sure this is the reason since the code is incomplete, but I hope it will help you somehow.