DevelopingBeaver
DevelopingBeaver

Reputation: 155

Best way to save a arraylist

This question has been answered before, but the solutions doesn't seem to work for me. I would like to know what the best way is to save an ArrayList.

I generate an ArrayList with all the installed applications on the phone. This list is shown in a ListView where the user can (de)select apps. This is all working fine. What I would like is that the Arraylist gets saved when the user presses a save button or when the activity calls onPause().

When the user returns to the list the user will see the list the way he saved/left it.

Here is my code:

onCreate

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_app_list);

    loadApps();
    loadListView();
    addClickListener();
}

loadApps

private void loadApps(){
    manager = getPackageManager();
    apps = new ArrayList<AppDetail>();

    if(apps.size()==0) {
        Intent i = new Intent(Intent.ACTION_MAIN, null);
        i.addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> availableActivities = manager.queryIntentActivities(i, 0);
        for (ResolveInfo ri : availableActivities) {
            AppDetail app = new AppDetail();
            app.label = ri.loadLabel(manager);
            app.name = ri.activityInfo.packageName;
            app.icon = ri.activityInfo.loadIcon(manager);
            app.allowed = false;
            apps.add(app);
        }
        Log.i("applist", apps.toString());
    }
}

AppDetail.class

public class AppDetail {
CharSequence label;
CharSequence name;
Drawable icon;
Boolean allowed;

loadListView

private void loadListView(){

    list = (ListView)findViewById(R.id.apps_list);

    adapter = new ArrayAdapter<AppDetail>(this, R.layout.list_item, apps) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = getLayoutInflater().inflate(R.layout.list_item, null);
            }

            ImageView appIcon = (ImageView)convertView.findViewById(R.id.item_app_icon);
            appIcon.setImageDrawable(apps.get(position).icon);

            TextView appLabel = (TextView)convertView.findViewById(R.id.item_app_label);
            appLabel.setText(apps.get(position).label);

            TextView appName = (TextView)convertView.findViewById(R.id.item_app_name);
            appName.setText(apps.get(position).name);

            if(list.isItemChecked(position)){convertView.setBackgroundColor(getResources().getColor(R.color.green));}
            if(!list.isItemChecked(position)){convertView.setBackgroundColor(getResources().getColor(R.color.white));}
            return convertView;
        }
    };
    list.setAdapter(adapter);
    list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}

addClickListener

private void addClickListener() {
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int pos,
                                long id) {
            checked = list.getCheckedItemPositions();
            ArrayList<AppDetail> allowedApps = new ArrayList<>();

            for (int i = 0; i < checked.size(); i++) {
                // Item position in adapter
                int position = checked.keyAt(i);
                // Add sport if it is checked i.e.) == TRUE!
                if (checked.valueAt(i)) {
                    allowedApps.add(adapter.getItem(position));
                }
            }
            adapter.notifyDataSetChanged();
            Log.i("", allowedApps.toString());
        }
    });
}

At this moment I'm creating two lists: List: list of all apps AllowedApps: list of checked (allowed) apps, to use in an other activity

Upvotes: 0

Views: 373

Answers (3)

juanhl
juanhl

Reputation: 1170

If you need saving your list when activity is paused, you have several ways to do it. First you need define the private list field in your activity.

private ArrayList<AppDetail> allowedApps;

1) Make AppDetail serializable and use onSaveInstanceState

public class AppDetail implements Serializable {
    CharSequence label;
    CharSequence name;
    Drawable icon;
    Boolean allowed;
}

---------------- EDIT -----------------

I would change Drawable icon field for int icon.

In your loadApps() method change the setence app.icon = ri.activityInfo.getIconResource();

In yout loadListView method change the setence appIcon.setImageResource(apps.get(position).icon);

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("allowedApps", allowedApps);
}

Retrieve the list in onCreate method

if (savedInstanceState != null) {
     allowedApps = (List<AppDetail>)savedInstanceState.getSerializable("allowedApps");
}else{
     allowedApps = new ArrayList<AppDetail>();
}

2) Use onRetainCustomNonConfigurationInstance

Return the list in onRetainCustomNonConfigurationInstance

@Override
public Object onRetainCustomNonConfigurationInstance() {
    return allowedApps;
}

Retrieve the list in onCreate method

Object allowedApps= getLastCustomNonConfigurationInstance();
if (allowedApps != null) {
    this.allowedApps = (List<AppDetail>) allowedApps;
}else{
    this.allowedApps = new ArrayList<AppDetail>();
}

Upvotes: 1

RehanZahoor
RehanZahoor

Reputation: 412

ArrayList is serializable. Save it as a serializable object in file on storage

Upvotes: 1

Prokash Sarkar
Prokash Sarkar

Reputation: 11873

I think you are looking for something like "Parcelable". It can save any ArrayList and retrieve back when you need it just like the Shared Preferences.

Please have a look here,

How to save custom ArrayList on Android screen rotate?

Upvotes: 1

Related Questions