【问题标题】:Best way to save a arraylist保存数组列表的最佳方法
【发布时间】:2015-08-03 01:09:18
【问题描述】:

这个问题之前已经回答过了,但这些解决方案似乎对我不起作用。我想知道保存 ArrayList 的最佳方法是什么。

我生成一个 ArrayList,其中包含手机上所有已安装的应用程序。此列表显示在 ListView 中,用户可以在其中(取消)选择应用程序。这一切都很好。我想要的是当用户按下保存按钮或活动调用 onPause() 时保存 Arraylist。

当用户返回列表时,用户将以他保存/离开的方式查看列表。

这是我的代码:

onCreate

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

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

加载应用程序

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;

加载列表视图

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());
        }
    });
}

此时我正在创建两个列表: 列表:所有应用程序的列表 AllowedApps:已检查(允许)的应用程序列表,用于其他活动

【问题讨论】:

  • AFAIK,您需要找到一种方法将其保存到内部存储上的文件并从那里填充。
  • 您说您已经研究了解决方案,但它们对您不起作用,请说明您具体尝试了什么以及为什么它不适合您的用例。
  • 序列化列表...
  • 应用程序关闭/手机关机后是否应该保留选择?如果是这样,您需要保存到数据库或文件中。即使不关闭应用程序,实际上也可以清除列表。阅读 Android 生命周期developer.android.com/training/basics/activity-lifecycle/…

标签: java android arraylist sharedpreferences android-adapter


【解决方案1】:

如果您需要在活动暂停时保存列表,您有多种方法可以做到。首先,您需要在活动中定义私有列表字段。

private ArrayList<AppDetail> allowedApps;

1) 使 AppDetail 可序列化并使用 onSaveInstanceState

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

---------------- 编辑 -----------------

我会将Drawable icon 字段更改为int icon。

在您的 loadApps() 方法中更改 setence app.icon = ri.activityInfo.getIconResource();

在你的 loadListView 方法中更改 setence appIcon.setImageResource(apps.get(position).icon);

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

在 onCreate 方法中获取列表

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

2) 使用 onRetainCustomNonConfigurationInstance

返回 onRetainCustomNonConfigurationInstance 中的列表

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

在 onCreate 方法中获取列表

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

【讨论】:

  • 感谢您的快速回答!我实现了第一种方法。当我旋转屏幕时,它会调用 onSaveInstanceState。当我在 onCreate 中记录 != null 时,它会正确记录列表。当我单击最近按钮(活动应用程序)时,应用程序崩溃Channel is unrecoverably broken and will be disposed!
  • 从按钮发布监听器。
  • 现在我使用 onClick 方法。我在 xml 文件中定义 onClick 的地方!还是您的意思是最近按钮的监听器?
  • 发布方法onClick then
  • public void submitButton(View v) { Toast.makeText(getApplicationContext(), " List submitted ", Toast.LENGTH_SHORT).show(); }
【解决方案2】:

我认为您正在寻找类似 “Parcelable” 的内容。它可以保存任何 ArrayList 并在您需要时检索它,就像共享首选项一样。

请看这里,

How to save custom ArrayList on Android screen rotate?

【讨论】:

    【解决方案3】:

    ArrayList 是可序列化的。将其作为可序列化对象保存在存储文件中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 2013-01-08
      • 2014-11-27
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2011-12-13
      相关资源
      最近更新 更多