【问题标题】:Refresh ListView after deletion删除后刷新ListView
【发布时间】:2015-10-25 23:51:57
【问题描述】:

我检查了很多堆栈溢出问题,但都没有帮助。 使用 onLongClickListener 删除项目后如何刷新我的 listView? 如您所见,adapter.notifyDataSetChanged()listView.invalidateViews() 都不起作用。

这是用必要的方法来找出想法的实现。

public class MainActivity extends AppCompatActivity {
public FloatingActionButton fabAddWord;
public Toolbar toolbar;
public ListView listView;
private RjecnikCursorAdapter adapter;

private RjecnikDB dbRjecnik;
private SQLiteDatabase db;
private Cursor cursor;

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

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    fabAddWord = (FloatingActionButton) findViewById(R.id.fabAddWord);
    listView = (ListView) findViewById(R.id.listView);

    dbRjecnik = new RjecnikDB(this);
    db = dbRjecnik.getWritableDatabase();
    String query = "SELECT * FROM " + RjecnikDB.TABLE;
    cursor = db.rawQuery(query, null);

    adapter = new RjecnikCursorAdapter(this, cursor);
    listView.setAdapter(adapter);

    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            deleteOnLongClick(cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC)));

            adapter.notifyDataSetChanged();
            listView.invalidateViews();

            return true;
        }
    });
}

public void deleteOnLongClick(String rijec) {
    SQLiteDatabase db = dbRjecnik.getWritableDatabase();
    db.delete(RjecnikDB.TABLE, RjecnikDB.COLUMN_RIJEC + " = ?", new String[] {rijec} );

    this.adapter.notifyDataSetChanged();
    this.listView.invalidateViews();

    db.close();
}

自定义适配器

public class RjecnikCursorAdapter extends CursorAdapter {

public RjecnikCursorAdapter (Context context, Cursor cursor) {
    super(context, cursor, 0);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return LayoutInflater.from(context).inflate(R.layout.item_word, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView tvSingleLineWord = (TextView) view.findViewById(R.id.tvSingleLineWord);

    // Extract properties from cursor
    String rijec = cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC));

    // Populate fields with extracted properties
    tvSingleLineWord.setText(rijec);
}

}

【问题讨论】:

  • 我相信你只是从数据库中删除而不是从适配器中删除?
  • 当我去另一个活动并返回时,已删除的 textView 消失了。那么,我应该如何从适配器中删除呢?

标签: android listview android-listview onlongclicklistener


【解决方案1】:

Adapter有数据缓存,所以ListView中的数据不会随着数据库中的数据变化而变化。您应该更改光标。

@Override
public void changeCursor(Cursor cursor) {
    mIndexer.setCursor(cursor);
    super.changeCursor(cursor);
}

把下面的代码放到你的OnItemLongClickListener

cursor = db.rawQuery(query, null);
adapter.changeCurosr(cursor);

【讨论】:

  • db.rawQuery(query, null); 第一个参数查询应该是SELECT * FROM TABLE_NAME ?
  • 是的,所以您可以将String query = "SELECT * FROM " + RjecnikDB.TABLE; 设置为final
  • 大数据库的情况下,频繁查询会影响速度吗?
  • 确定性。我建议你不要使用这种方法。拆分数据库部分和UI部分,然后用异步的方法加载数据。
  • 顺便说一下,你应该从数据库异步加载数据。如果您有任何其他问题,请给我发送电子邮件。 zhenghuiy@gmail.com
【解决方案2】:

您必须只使用 notifyDataSetChanged() 来刷新您的 listView 数据,invalidateViews() 只会重绘可见项目,但它们上没有任何变化(例如更改字体)。

请注意,建议您在 UI 线程上运行 notifyDataSetChanged()。

编辑 2 :您可以使用 BaseAdapter 而不是 CursorAdapter,如下所示

public class RjecnikCursorAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<String> rjecnikList;


    public RjecnikCursorAdapter(Activity activity, List<String> rjecnikList) {
        this.activity = activity;
        this.rjecnikList = rjecnikList;
    }

    @Override
    public int getCount() {
        return rjecnikList.size();
    }

    @Override
    public Object getItem(int location) {
        return rjecnikList.get(location);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.item_word, null);

        TextView tvSingleLineWord = (TextView) view.findViewById(R.id.tvSingleLineWord);

        tvSingleLineWord.setText(String.valueOf(rjecnikList.get(position)));


        return convertView;
    }

}

在你的活动中:

    public class MainActivity extends AppCompatActivity {
    public FloatingActionButton fabAddWord;
    public Toolbar toolbar;
    public ListView listView;
    public  List<String> mylist;
    private RjecnikCursorAdapter adapter;

    private RjecnikDB dbRjecnik;
    private SQLiteDatabase db;
    private Cursor cursor;

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

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        fabAddWord = (FloatingActionButton) findViewById(R.id.fabAddWord);
        listView = (ListView) findViewById(R.id.listView);

        dbRjecnik = new RjecnikDB(this);
        db = dbRjecnik.getWritableDatabase();
        String query = "SELECT * FROM " + RjecnikDB.TABLE;
        cursor = db.rawQuery(query, null);
        mylist = new ArrayList<>();

        if (cursor.moveToFirst()){

 do{
//change this with your column data
      String data = cursor.getString(cursor.getColumnIndex("data");

      mylist.add(data);

   }while(cursor.moveToNext());

}

cursor.close();
        adapter = new RjecnikCursorAdapter(this, mylist);
         listView.setAdapter(adapter);

        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                deleteOnLongClick(cursor.getString(cursor.getColumnIndex(RjecnikDB.COLUMN_RIJEC)));
                mylist.remove(position);
                adapter.notifyDataSetChanged();
                listView.invalidateViews();

                return true;
            }
        });
    }

    public void deleteOnLongClick(String rijec) {
        SQLiteDatabase db = dbRjecnik.getWritableDatabase();
        db.delete(RjecnikDB.TABLE, RjecnikDB.COLUMN_RIJEC + " = ?", new String[] {rijec} );

        this.adapter.notifyDataSetChanged();
        this.listView.invalidateViews();

        db.close();
    }

【讨论】:

  • 还是不行。我添加了new Thread(new Runnable() { @Override public void run() { MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); } }); } }).start();,只有在我去另一个活动并返回后,删除的 textView 才会被删除。
  • 1- 请问您可以通过添加适配器代码来编辑您的帖子吗? 2-要在 UI 线程上运行代码,您不需要使用另一个线程,只需 runOnUiThrad
  • 我没有 listView 的删除方法。只有少数人实际上试图删除像removeView, removeViewAt, removeFooterView 这样的视图。所有这些都会导致像removeViewAt(int) is not supported in AdapterView这样的错误
  • 是的,对不起,我与 List 混淆了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多