【问题标题】:How to Keep ArrayList Value When Changing Activity in Android在 Android 中更改 Activity 时如何保持 ArrayList 的值
【发布时间】:2018-12-22 23:44:51
【问题描述】:

这是 ViewActivity

public class ViewActivity extends AppCompatActivity {

    private ListView lvPerson;
    private PersonListAdapter adapter;
    public List<Person> mPersonList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view);

        lvPerson = (ListView)findViewById(R.id.listView);

        //Add new person
        Intent intent = getIntent();
        if(intent.hasExtra("add")){
            String name = intent.getStringExtra("name");
            String email = intent.getStringExtra("email");
            String address = intent.getStringExtra("address");
            mPersonList.add(new Person(name, email, address));
            Toast.makeText(getApplicationContext(), "Data berhasil ditambahkan", Toast.LENGTH_SHORT).show();
        }

        //Init adapter
        adapter = new PersonListAdapter(getApplicationContext(), mPersonList);
        lvPerson.setAdapter(adapter);

    }
}

这是输入活动

public class InputActivity extends AppCompatActivity {

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

    public void saveButtonClicked(View view){

        EditText name = (EditText) findViewById(R.id.editTextName);
        EditText email = (EditText) findViewById(R.id.editTextEmail);
        EditText address = (EditText) findViewById(R.id.editTextAddress);

        String strName = name.getText().toString();
        String strEmail = email.getText().toString();
        String strAddress = address.getText().toString();

        Intent intent = new Intent(this, ViewActivity.class);
        intent.putExtra("add", true);
        intent.putExtra("name", strName);
        intent.putExtra("email", strEmail);
        intent.putExtra("address", strAddress);
        startActivity(intent);

    }
}

显示我的流程是当在 InputActivity 中单击保存按钮时,它将在 ViewActivity 中运行“添加人员”代码并将数据从表单添加到 ArrayList。

这是可行的,但是当我使用意图更改活动并返回 ViewActivity 时,ArrayList 数据消失了。

我想要的是保留我已经在 InputActivity 中输入的所有值。

希望你明白我的意思:)

【问题讨论】:

  • 您想无限期地保留它,还是只在单个应用会话中保留它?
  • 仅在单个应用会话中
  • 但问题是当我开始新活动时,ArrayList 数据消失了。我太堆栈了,我对android一无所知。顺便说一句,这是我的学校任务。这是我第一次学习 Android @TylerV
  • 感谢您的澄清。这里有很多关于在活动之间来回传递数据的好答案。我用不同的方法添加了一个。

标签: java android arrays android-studio arraylist


【解决方案1】:

这里有一些很好的答案,但由于您只希望它在一个应用会话期间持续存在,因此我将添加另一种方法,一个单例来保存数据:

class DataHolder {
    final List<Person> people = new ArrayList<>;

    private DataHolder() {}

    static DataHolder getInstance() {
        if( instance == null ) {
            instance = new DataHolder();
        }
        return instance;
    }

    private static DataHolder instance;
}

在任一活动(或应用程序中的任何位置)中,您都可以使用以下方式访问人员列表

List<Person> ppl = DataHolder.getInstance().people;

例如,您将替换

public List<Person> mPersonList = new ArrayList<>();

// not sure why that was public...
private List<Person> mPersonList = DataHolder.getInstance().people;

它只会持续到您当前的应用会话,但如果您想在将来保存它们,您可以将后端数据库添加到 DataHolder,这样每次添加人员时它都会自动保存在某个位置。

【讨论】:

  • 太棒了!!这是完全有效的,非常简单。非常感谢我。你救了我得 D 分数 :)
【解决方案2】:

在 InputActivity 中覆盖 onSaveInstanceState(Bundle) 以保存您想要的任何数据,然后在同一活动中覆盖 onRestoreInstanceState(Bundle) 以取回值。使用 Bundle,您可以存储几乎任何您想要的数据。我会推荐这样的东西:

public class ViewActivity extends AppCompatActivity {

private ListView lvPerson;
private PersonListAdapter adapter;
public List<Person> mPersonList = new ArrayList<>();

@Override 
protected void onSaveInstanceState (Bundle outState) { 
    outState.putStringArrayList("mPersonList", mPersonList); //I assume you want to mPersonList
}

@Override
protected void onRestoreInstanceState (Bundle savedInstanceState) {
    this.mPersonList = savedInstanceState.getStringArrayList("mPersonList"); //on coming back retrieve all values using key
        }

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_view);

    lvPerson = (ListView)findViewById(R.id.listView);

    //Add new person
    Intent intent = getIntent();
    if(intent.hasExtra("add")){
        String name = intent.getStringExtra("name");
        String email = intent.getStringExtra("email");
        String address = intent.getStringExtra("address");
        mPersonList.add(new Person(name, email, address));
        Toast.makeText(getApplicationContext(), "Data berhasil ditambahkan", Toast.LENGTH_SHORT).show();
    }

    //Init adapter
    adapter = new PersonListAdapter(getApplicationContext(), mPersonList);
    lvPerson.setAdapter(adapter);

}
}

【讨论】:

  • 当我将数据添加到 ArrayList 时,问题出在 ViewActivity 中。我已添加,但当我更改活动时,数据将消失
  • 那么你应该在ViewActivity中重写这两个添加的方法。让我告诉你怎么做。
  • 但我在声明 ArrayList "public List mPersonList = new ArrayList();" 时使用 "List"它给我错误。你知道如何解决吗?
  • 亲爱的@DimasAdiAndrea List是一个接口,ArrayList是一个实现List的类,在其他几个接口中(ArrayList类也实现了Serializable,所以我建议使用ArrayList
  • 更主要的想法是重写两种方法来保存数据并取回数据。您可以根据您的要求进行调整以实现它
【解决方案3】:

您所做的实际上非常非常糟糕,因为您只是为要添加和创建的每个人创建一个又一个活动。它浪费内存和电力。

相反,您应该寻找的只是将 InputActivity 的结果返回给 ViewActivity。

在您的 ViewActivity 中,不要调用 startActivity(intent),而是使用 startActivityForResult(intent, REQUEST_CODE)。然后覆盖onActivityResult(),以便您可以处理返回给 ViewActivity 的结果。

在InputActivity中,不要调用startActivity(),而是将intent返回给ViewActivity。

这样的一个例子是这样的:

查看活动

public class ViewActivity extends AppCompatActivity {

    private ListView lvPerson;
    private PersonListAdapter adapter;
    public List<Person> mPersonList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view);

        lvPerson = (ListView)findViewById(R.id.listView);

        //Init adapter
        adapter = new PersonListAdapter(getApplicationContext(), mPersonList);
        lvPerson.setAdapter(adapter);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == RESULT_OK){
            String name = data.getStringExtra("name");
            String email = data.getStringExtra("email");
            String address = data.getStringExtra("address");
            mPersonList.add(new Person(name, email, address));
            adapter.notifyDataSetChanged();
            Toast.makeText(getApplicationContext(), "Data berhasil ditambahkan", Toast.LENGTH_SHORT).show();
        }
    }

}

输入活动

public class InputActivity extends AppCompatActivity {

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

    public void saveButtonClicked(View view){

        EditText name = (EditText) findViewById(R.id.editTextName);
        EditText email = (EditText) findViewById(R.id.editTextEmail);
        EditText address = (EditText) findViewById(R.id.editTextAddress);

        String strName = name.getText().toString();
        String strEmail = email.getText().toString();
        String strAddress = address.getText().toString();

        Intent intent = new Intent();
        intent.putExtra("add", true);
        intent.putExtra("name", strName);
        intent.putExtra("email", strEmail);
        intent.putExtra("address", strAddress);
        setResult(RESULT_OK, intent);
        finish();    
    }
}

这样做可以避免再次重新创建 ViewActivity,因此您不必重新创建所有视图并重新填充列表。您只需重用现有的 ViewActivity 并将结果添加到现有列表中。

【讨论】:

    【解决方案4】:

    如果我理解正确,您的流程如下: 1.) ViewActivity -> Intent -> InputActivity 2.) InputActivity -> Intent -> ViewActivity

    如果是这种情况,您应该阅读更多有关 Android 中的“活动生命周期”的信息: https://developer.android.com/guide/components/activities/activity-lifecycle

    简而言之: onCreate 仅在创建 ViewActivity 时被调用。如果您从那里转到 InputActivity 然后返回 -> ViewActivity 已经存在,因此不会调用 oncreate 。

    对于您的情况,我想到的一个解决方案是 startActivityForResult。这里有一个关于如何使用它的例子: How to manage `startActivityForResult` on Android?

    另一个通用提示,因为您似乎对 android 开发相当陌生:大量使用断点和日志 (https://developer.android.com/reference/android/util/Log) 以更好地了解事情发生的时间和地点。并且不要只使用教程在 Android 中开始开发。阅读一些更详细地解释一些 android 细节的初学者指南/书籍(如 Activity-Lifecycle)并没有什么坏处

    【讨论】:

      【解决方案5】:

      您可以使用 Gson/Jackson/或其他任何方式将其序列化为字符串,然后使用 [SharedPreferences][1] 保存它。然后在新活动中,您只需从 SharedPreferences 加载它。

      【讨论】:

      • 虽然这在技术上可行,但 android 已经让您能够使用 onSaveInstanceStateonRestoreInstanceState 保存状态和活动
      • 他试图在两个活动之间传递一个类。至少这是我对他的问题的理解,我可能错了。
      猜你喜欢
      • 1970-01-01
      • 2014-07-02
      • 2013-02-15
      • 2021-04-02
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      相关资源
      最近更新 更多