【问题标题】:ListView updates the entry only when the application is restarted againListView 仅在应用程序再次重新启动时更新条目
【发布时间】:2017-10-17 13:32:58
【问题描述】:

在这个应用程序中,我有一个listview 和一个sqlitedatabase。有一个floating action button,单击它会显示一个dialog box,其中包含两个edittext,一个用于名称,另一个用于编号。问题是在单击dialog boxadd 选项后,该条目未显示在listview 上。但是当 activity 被销毁并在 activity 上再次调用 onCreate 时,将显示该条目。

我尝试使用adapter.notifyDataSetChanged(),但它不起作用。代码如下:

代码

public class DetailsActivity extends AppCompatActivity {

private DatabaseManager manager;
private ListView listView;
private SimpleCursorAdapter adapter;

final String[] from=new String[] {UserDatabase.NAME,UserDatabase.NUMBER};

final int[] to=new int[] {R.id.nameDisplay,R.id.phoneDisplay};


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

    manager = new DatabaseManager(getApplicationContext());
    manager.open();
    Cursor cursor=manager.fetch();

    listView = (ListView) findViewById(R.id.listViewId);
    listView.setEmptyView(findViewById(R.id.empty));

    adapter = new SimpleCursorAdapter(getApplicationContext(),
            R.layout.row_item, cursor, from, to, 0);
    adapter.notifyDataSetChanged();

    listView.setAdapter(adapter);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(DetailsActivity.this);
            LayoutInflater inflater = DetailsActivity.this.getLayoutInflater();
            final View dialogView = inflater.inflate(R.layout.custom_dialog, null);
            dialogBuilder.setView(dialogView);
            final EditText name = (EditText) dialogView.findViewById(R.id.dialogEditNmID);
            final EditText phone = (EditText) dialogView.findViewById(R.id.dialogEditPhID);

            dialogBuilder.setTitle("Add Details");
            dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (!TextUtils.isEmpty(name.getText().toString()) &&
                            !TextUtils.isEmpty(phone.getText().toString())) {
                        /*adapter.notifyDataSetChanged();
                        manager.insert(name.getText().toString(), phone.getText().toString());
                        Toast.makeText(getApplicationContext(),
                                "Added " + name.getText().toString(), Toast.LENGTH_SHORT).show();*/
                        insertData(name.getText().toString(),phone.getText().toString());
                    } else {
                        Toast.makeText(getApplicationContext(),
                                "Empty field(s)", Toast.LENGTH_SHORT).show();
                    }

                }
            });

            dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });

            AlertDialog b = dialogBuilder.create();
            b.show();
            //  listView.setAdapter(adapter);
            //adapter.notifyDataSetChanged();
        }
    });
}

public void insertData(String fname,String phnumber){
    manager.insert(fname,phnumber);
    listView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}
}

有些语句被注释了,因为我试图得到想要的结果但没有得到。

【问题讨论】:

    标签: android listview simplecursoradapter


    【解决方案1】:

    这里有几件事你必须改变。看看这段代码:

    dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (!TextUtils.isEmpty(name.getText().toString()) && !TextUtils.isEmpty(phone.getText().toString())) {
                adapter.notifyDataSetChanged();
                manager.insert(name.getText().toString(), phone.getText().toString());
                Toast.makeText(getApplicationContext(), "Added " + name.getText().toString(), Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(), "Empty field(s)", Toast.LENGTH_SHORT).show();
            }
        }
    });
    
    1. 当您单击“添加”按钮时,您会立即致电adapter.notifyDataSetChanged();。在您的情况下,您应该只在将项目添加到 listView 之后调用它,但您还没有添加任何内容。
    2. 您使用manager.insert(name.getText().toString(), phone.getText().toString()); 将数据插入到您的数据库中,但您没有使用新添加的数据更新listView。您需要将该数据插入数据库,然后将该数据添加到listView

    现在您可以拨打adapter.notifyDataSetChanged();

    我建议当您要插入数据库时​​,创建一个插入数据的方法,将新数据添加到listView,然后告诉适配器刷新。

    编辑

    关于您最近的编辑,还有一些事情需要注意。

    1. 您不应该在方法中使用listView.setAdapter(adapter)。您第一次就做对了(在 onCreate() 中,但在对话框生成器之前)。
    2. 你调用manager.insert(fname,phnumber);,但还是没有将新插入的数据添加到listView

    以下是您的方法中应该包含的伪代码:

    public void insertData(String fname,String phnumber){
        manager.insert(fname,phnumber);
        // Code to add the data you just inserted into the manager above to `listView`.
        adapter.notifyDataSetChanged();
    }
    

    请记住,adapter.notifyDataSetChanged(); 仅在 listView 发生更改时更新 listView,并且截至目前您尚未添加/删除/修改 listView

    【讨论】:

      【解决方案2】:

      在数据库中插入条目后,您应该再次获取数据,以便您的列表具有最新条目。因此,您可以修改代码以便能够将数据点添加到您传递给适配器的列表中,或者在插入之后和 notifyDatasetChanged() 之前从数据库中重新获取数据。

      【讨论】:

      • 所以,在onClick 中的adapter.notifyDataSetChanged(); manager.insert(name.getText().toString(), phone.getText().toString()); 之后,您希望我从cursor=manager.fetch(); 之类的数据库中获取数据,然后设置listview adapter
      • adapter.notifyDataSetChanged 之前。本质上,您正在使用一个列表,该列表传递给您的列表视图正在使用的适配器。当您插入数据库时​​,您还需要更新(添加新条目)适配器也引用的列表。这一切都需要在 onNotifyDatasetChanged 之前完成。请参阅@Michael 的答案。他解释得很详细。
      • 是的,我接受了他的建议并更改了我的代码。你能看看吗
      • 不正确。从 onClick 外部取消注释这两行。这是您的初始列表设置 //adapter.notifyDataSetChanged(); // listView.setAdapter(适配器);然后在您的单击中的 insertData 之后插入这 3 行。 adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.row_item, cursor, from, to, 0);适配器.notifyDataSetChanged(); listView.setAdapter(适配器);不是最好的方法,但应该让它发挥作用。
      • 还是不行。我必须重新启动应用程序才能显示上次输入的条目。
      【解决方案3】:

      我对代码做了一些更改,请尝试一下,让我知道它是否有帮助

      public class DetailsActivity extends AppCompatActivity {
      
      private DatabaseManager manager;
      private ListView listView;
      private SimpleCursorAdapter adapter;
      
      final String[] from=new String[] {UserDatabase.NAME,UserDatabase.NUMBER};
      
      final int[] to=new int[] {R.id.nameDisplay,R.id.phoneDisplay};
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_details);
      
          manager = new DatabaseManager(getApplicationContext());
          manager.open();
      
      
          listView = (ListView) findViewById(R.id.listViewId);
          listView.setEmptyView(findViewById(R.id.empty));
          adapter = new SimpleCursorAdapter(getApplicationContext(),R.layout.row_item, cursor, from, to, 0);
          //adapter.notifyDataSetChanged();
      
          FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
          fab.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(DetailsActivity.this);
                  LayoutInflater inflater = DetailsActivity.this.getLayoutInflater();
                  final View dialogView = inflater.inflate(R.layout.custom_dialog, null);
                  dialogBuilder.setView(dialogView);
                  final EditText name = (EditText) dialogView.findViewById(R.id.dialogEditNmID);
                  final EditText phone = (EditText) dialogView.findViewById(R.id.dialogEditPhID);
      
                  dialogBuilder.setTitle("Add Details");
                  dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          if (!TextUtils.isEmpty(name.getText().toString()) &&
                                  !TextUtils.isEmpty(phone.getText().toString())) {
                              adapter.notifyDataSetChanged();
                              manager.insert(name.getText().toString(), phone.getText().toString());
                              Toast.makeText(getApplicationContext(),
                                      "Added " + name.getText().toString(), Toast.LENGTH_SHORT).show();
      
                              Cursor cursor = manager.fetch();
      
                              listView.setAdapter(adapter);
                          } else {
                              Toast.makeText(getApplicationContext(),
                                      "Empty field(s)", Toast.LENGTH_SHORT).show();
                          }
      
                      }
                  });
      
                  dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                      }
                  });
      
                  AlertDialog b = dialogBuilder.create();
                  b.show();
                  //  listView.setAdapter(adapter);
                  //adapter.notifyDataSetChanged();
              }
          });
      }}
      

      【讨论】:

      • 应用程序因null object reference 而崩溃。您在 onClick 方法中初始化了 adapter,但不是在它之前。
      • 我已将它添加到 onCreate 方法中,我认为它现在应该可以工作了
      • 现在您已经在onClick 方法中初始化了cursorsimpleCursorAdapter 的参数包含光标。
      • 只需将 Cursor 对象设为全局即可。
      【解决方案4】:

      插入操作后尝试使用 notifyDataSetChanged。在您呼叫(尝试呼叫)的所有地方,通知经理数据尚未更改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        相关资源
        最近更新 更多