【问题标题】:Saving Listview data保存 Listview 数据
【发布时间】:2015-07-15 23:18:55
【问题描述】:

我有一个问题,我有一个列表视图,转到另一个活动以附加用户值,而不是将这些值实现到列表视图。但是,如果我返回该活动并附加一组新值,当我返回我的 listview 活动时,新值将被实现,但旧值已被删除。 sqlite数据库会解决这个问题吗?还是与正在重新创建的实际列表有关?

ListActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.personalproject.peter.timerapp.TestingForAlarmData.TestAlarm;

import java.util.ArrayList;
import java.util.List;


public class ListOfAlarms extends ActionBarActivity {
    private static final int RESULT = 1000;

    List<TestAlarm> alarms = new ArrayList<>();
    String title;
    int totalTime;

    ListView listOfAlarms;
    ArrayAdapter<TestAlarm> alarmArrayAdapter;

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



       final TextView emptyViewForList = (TextView) findViewById(R.id.emptyTextViewForList);

       listOfAlarms = (ListView) findViewById(R.id.listView);
       alarmArrayAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, alarms);
       listOfAlarms.setAdapter(alarmArrayAdapter);

//        if(listOfAlarms.getCount() <= 0){
//            emptyViewForList.setText("No Alarms Currently Available");
//            listOfAlarms.setEmptyView(emptyViewForList);
//        }

        listOfAlarms.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               alarms.get(position);

                Intent clockDownActivity = new Intent(ListOfAlarms.this, CountDownAct.class);
               clockDownActivity.putExtra("Title", title);
               clockDownActivity.putExtra("totalTime", totalTime);
                startActivity(clockDownActivity);
           }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_list_of_alarms, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void goToFillOut(View view) {

            Intent goingToFillOut = new Intent(this, Test.class);
            startActivityForResult(goingToFillOut, RESULT);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == RESULT && resultCode == RESULT_OK){


               title = data.getStringExtra("title");
                totalTime = data.getIntExtra("totalTime", 0);

                alarms.add(new TestAlarm(title, totalTime));

               alarmArrayAdapter.notifyDataSetChanged();

        }
    }


}

第二个活动

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class Test extends ActionBarActivity {
    private static final String LOGTAG = "Test.class";
    private static final long timeInterval = 1000;


    private Button complete;
    private EditText titleEditText;
    private EditText hourEditText;
    private EditText minuteEditText;
    private EditText secondEditText;
    public static   int hour;



    public static int minute;
    public static int second;
    public static String title;




    public int actualTimeFiniliazedInMilliSeconds;


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

        titleEditText = (EditText) findViewById(R.id.titleEditText);
        hourEditText = (EditText) findViewById(R.id.hourEditText);
        minuteEditText = (EditText) findViewById(R.id.minuteEditText);
        secondEditText = (EditText) findViewById(R.id.secondEditText);

        complete = (Button) findViewById(R.id.completeButton);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    public void saveTimer(View view) {

        if(titleEditText.getText().toString().isEmpty() || hourEditText.getText().toString().isEmpty()
                || minuteEditText.getText().toString().isEmpty() || secondEditText.getText().toString().isEmpty()) {

            Toast.makeText(this, "Oops you forgot one", Toast.LENGTH_LONG).show();
            return;

        }
//            complete.setVisibility(View.GONE);
            title = titleEditText.getText().toString();
            hour = Integer.parseInt(hourEditText.getText().toString().trim());
            minute = Integer.parseInt(minuteEditText.getText().toString().trim());
            second = Integer.parseInt(secondEditText.getText().toString().trim());

            hour *= 3600000;
            minute *= 60000;
            second *= 1000;

        actualTimeFiniliazedInMilliSeconds = hour + minute + second;


        Intent intent = new Intent(Test.this, ListOfAlarms.class);
        intent.putExtra("title", title);
        intent.putExtra("totalTime", actualTimeFiniliazedInMilliSeconds);
        setResult(RESULT_OK, intent);
        finish();

    }



}

Alarm.java

public class TestAlarm {

    public String title;
    public int totalTime;

    public TestAlarm (String title, int totalTime) {
        this.title = title;
        this.totalTime = totalTime;
    }

    @Override
    public String toString() {
        return title;
    }
}

【问题讨论】:

  • 你去/去活动怎么样?您是先调用完成还是在onResume() 中创建它。提供上下文的一些代码会有所帮助
  • @codeMagic 是的,我刚刚输入了它

标签: java android android-listview android-sqlite


【解决方案1】:

只需尝试以下步骤,这种情况不需要使用SqliteDB。

创建一个单例类 例如:

    public class Singleton {
      private static Singleton uniqInstance;

      private  List<TestAlarm> mAlarms = new ArrayList<>();

      private Singleton() {
      }

      public static synchronized Singleton getInstance() {
        if (uniqInstance == null) {
          uniqInstance = new Singleton();
        }
        return uniqInstance;
      }

    public void setAllarms(List<TestAlarm> alarms){
        this.mAlarms  = alarms;
   }

public List<TestAlarm> getAllarms(){
  return this.mAlarms;
}

    }

导航到另一个活动时保存单例类的警报

 listOfAlarms.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Singleton .getInstance().setAllarms(alarms); // Save the Collection

               alarms.get(position);

                Intent clockDownActivity = new Intent(ListOfAlarms.this, CountDownAct.class);
               clockDownActivity.putExtra("Title", title);
               clockDownActivity.putExtra("totalTime", totalTime);
                startActivity(clockDownActivity);
           }
        });

onActivityResult 从单例类中检索保存的集合

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == RESULT && resultCode == RESULT_OK){


               title = data.getStringExtra("title");
                totalTime = data.getIntExtra("totalTime", 0);


               Singleton.getInstance().getAllarms().add(new TestAlarm(title, totalTime));

               this.alarms  = Singleton.getInstance().getAllarms();
               alarmArrayAdapter.notifyDataSetChanged();

        }
    }

【讨论】:

  • 非常准确的说明到目前为止,我非常感谢您的帮助。但是现在当我去填写活动并返回到列表视图活动时,数据并没有完全显示。
【解决方案2】:

发生的情况是,当您离开并返回活动时,Android 正在重新创建活动和列表视图。因此,您需要一些方法来保存此更改的数据。

使用 sqlite 数据库可以解决问题,因为数据库将是永久存储,并且会长期保存信息(例如,如果用户关闭电话)。

另一种解决方案是实现 onSaveInstanceState 和 onRestoreInstanceState,这将保存有关变化的活动(或方向)的信息。如果他们关闭手机,信息就会丢失。

从您的问题来看,您似乎不需要长期保存信息,并且实现 onSaveInstanceState 的工作量比 sqlite 少。

【讨论】:

  • 感谢您提供信息,现在我将在哪里实现 onSaveInstanceStae 和 onRestoreInstanceState ListView 活动或 userInput 活动。我应该如何向列表视图添加新项目?
  • onSaveInstanceState 和 onRestoreInstanceState 将被添加到您的主 UI 活动中。 Android 将在离开您的 UI 活动时调用 onSaveInstanceState(因此您可以在此处保存警报列表)。当它重新创建活动时,它会调用 onRestoreInstanceState 您可以获取该信息并将其放回警报状态。此时,您的警报列表应该与关闭活动时相同,并且您可以像现在一样添加新条目。
【解决方案3】:

您正在使用

创建 Activity 的新实例
Intent intent = new Intent(Test.this, ListOfAlarms.class);

所以一切都重新创建了。

为避免这种情况,您需要在创建Intent 时使用一个空的构造函数,该构造函数将被发送回起始活动。

    Intent intent = new Intent(); // this should be empty
    intent.putExtra("title", title);
    intent.putExtra("totalTime", actualTimeFiniliazedInMilliSeconds);
    setResult(RESULT_OK, intent);
    finish();

见Going back to previous activity with different Intent value

和

The documentation

【讨论】:

  • 我刚刚这样做了,列表视图仍然没有更新
  • 所以当你带着LV回到活动时,你仍然有同样的问题,旧数据不存在但新数据存在?此外,当您第一次创建活动警报时,它似乎是空的。看看我的编辑,这是你所做的改变
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-27
相关资源
最近更新 更多