Android的:如何重新查询光标删除数据库行之后刷新的ListView? [英] Android: How to requery a Cursor to refresh ListView after deleting database row?

查看:250
本文介绍了Android的:如何重新查询光标删除数据库行之后刷新的ListView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些帮助,我的code在这里,它的驾驶我坚果。这可能是一个小白的问题,但我是很新的这一切的SQLite数据库内光标适配器-的ListView,做它,正确-东西

我有什么:

在我的 MainActivity 我有一个的ListView 。我使用 SQLite数据库并填充的ListView 与自定义适配器延长 SimpleCursorAdapter 。通过点击一个项目在我的动作条我激活上下文操作模式。一切工作至今。

我要什么:

通过点击我的 ListView项特定的图标将根据数据库行应该被删除,的ListView 应进行刷新。

我的问题:

我如何更新我的光标和我的的ListView 是否正确?当我不在使用 cursor.requery()我的 OnClickListener 和使用光标= dbm.getIOIOSensorsCursor(),而不是我得到一个 CursorIndexOutOfBoundsException 低于该行几行

  int型的state = cursor.getInt(cursor.getColumnIndex(IOIOSensorSchema.STATE));
 

我的应用程序崩溃,但重装后的数据库已被删除,根据 ListView项走了。

我想撞车必须是与 _position 中的get getView 的方法,因为 _position 最后。但是,当我使用 cursor.requery()一切正常,因为它应该。

但是... (总有一个但是)这个方法去precated,它的文档中说的不要使用这个...的。我是正确的编码的一个朋友(我还是一个初学者,想学code以正确的方式,而不是快速和肮脏的),想知道如何做到这一点的权利。我不知道这是否是重要的,但我只在我的(非常快)的Nexus 4,测试我的应用程序似乎有没有问题刷新光标速度不够快,但我不知道这是否会在较慢的设备。在情况下,它是非常重要的,你我的数据库将包含10〜20行,12列。我想这是一个非常小的数据库,但正如我在开始时说,这是大家很新的给我。

下面是我的自定义适配器相关code:

 公共类IOIOSensorCursorAdapterCam扩展SimpleCursorAdapter
{
静态类ViewHolder
{
ImageView的stateIV,removeIV;
TextView的nameTV,pinNumberTV,feedIDTV,freqTV;
}

私人上下文CTX;
私人光标指针;
私人IodDatabaseManager DBM;

公共IOIOSensorCursorAdapterCam(上下文_context,INT _layout,
    光标_cursor,字符串[] _from,INT [] _​​to,诠释_flags)
{
超(_context,_layout,_cursor,_from,_to,_flags);
CTX = _context;
光标= _cursor;
DBM =新IodDatabaseManager(_context);
}

@覆盖
公共查看getView(最终诠释_position,查看_convertView,
    的ViewGroup _parent)
{
ViewHolder支架=无效;

LayoutInflater充气=(LayoutInflater)CTX
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

//没有认为在这个位置,我们创建了一个新的。在这种情况下
//通过膨胀的XML布局。
如果(_convertView == NULL)
{
    //充气布局
    _convertView = inflater.inflate(R.layout.listview_item_sensor_cam,
        空值);

    持有人=新ViewHolder();
    holder.stateIV =(ImageView的)_convertView
        .findViewById(R.id.stateImageView);
    holder.nameTV =(TextView中)_convertView
        .findViewById(R.id.sensorNameTextView);
    holder.pinNumberTV =(TextView中)_convertView
        .findViewById(R.id.sensorPinNumberTextView);
    holder.feedIDTV =(TextView中)_convertView
        .findViewById(R.id.sensorFeedIDTextView);
    holder.freqTV =(TextView中)_convertView
        .findViewById(R.id.sensorFrequencyTextView);
    holder.removeIV =(ImageView的)_convertView
        .findViewById(R.id.removeImageView);
    _convertView.setTag(保持器);
}
//我们回收一个视图已经存在。
其他
{
    支架=(ViewHolder)_convertView.getTag();
}

//设置一个OnClickListener的删除图标
holder.removeIV.setOnClickListener(新OnClickListener()
{
    @燮pressWarnings(德precation)
    @覆盖
    公共无效的onClick(查看_view)
    {
    cursor.moveToPosition(_position);

    //删除传感器从数据库这里
    INT sensorID = cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    //这导致了CursorIndexOutOfBoundsException,不能
    //用来刷新的ListView
//光标= dbm.getIOIOSensorsCursor();

    //刷新的ListView
    cursor.requery();
    notifyDataSetChanged();
    }
});

cursor.moveToPosition(_position);

如果(cursor.getCount()大于0)
{
    INT状态= cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.STATE));

    如果(国家== 0)
    {
    holder.stateIV.setImageResource(R.drawable.av_play_over_video);
    holder.stateIV.setColorFilter(ctx.getResources()的getColor(
        R.color.hint_lighter_gray));
    // _convertView.setAlpha((浮点)0.5);
    holder.nameTV.setTextColor(ctx.getResources()的getColor(
        R.color.hint_darker_gray));
    }
    其他
    {
    holder.stateIV.setImageResource(R.drawable.av_pause_over_video);
    holder.stateIV.setColorFilter(ctx.getResources()的getColor(
        android.R.color.holo_green_light));
    // _convertView.setAlpha((浮点)1);
    holder.nameTV.setTextColor(ctx.getResources()的getColor(
        android.R.color.black));
    }

    //设置传感器的名称为根据的TextView
    字符串sensorName = cursor.getString(光标
        .getColumnIndex(IOIOSensorSchema.NAME));
    holder.nameTV.setText(sensorName);

    //设置传感器的引脚数为根据的TextView
    INT pinNumber = cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.PIN_NUMBER));
    holder.pinNumberTV.setText(+ pinNumber);

    //设置传感器的进料ID为根据的TextView
    INT feedID = cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.FEED_ID));
    holder.feedIDTV.setText(+ feedID);

    //设置传感器的频率为依据的TextView
    INT频率= cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.FREQUENCY));
    INT TIMEUNIT = cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.TIME_UNIT));
    字符串frequencyTextViewText =;
    开关(TIMEUNIT)
    {
    案例IodIOIOSensor.TIME_UNIT_MINUTES:
    frequencyTextViewText =频率+分;
    打破;
    案例IodIOIOSensor.TIME_UNIT_HOURS:
    frequencyTextViewText =频率+H;
    打破;
    默认:
    frequencyTextViewText =频率+秒;
    打破;
    }
    holder.freqTV.setText(frequencyTextViewText);
}
返回_convertView;
}
}
 

编辑:

下面是从OnCickListener我的相关code inplementing解决方案后:

  //设置一个OnClickListener的删除图标
holder.removeIV.setOnClickListener(新OnClickListener()
{
    @覆盖
    公共无效的onClick(查看_view)
    {
    cursor.moveToPosition(_position);

    //删除传感器从数据库这里
    INT sensorID = cursor.getInt(光标
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    Toast.makeText(CTX,R.string.toast_sensor_deleted,
        Toast.LENGTH_SHORT).show();

    //刷新的ListView
    光标= dbm.getIOIOSensorsCursor();
    swapCursor(光标);

    notifyDataSetChanged();
    }
});
 

解决方案
  

我如何更新我的光标和我的ListView正确?

您用C再次运行$ C $,以获得光标刷新[你]光标,使用code您用来创建原始光标(在后台线程,请)。您刷新的ListView 致电 changeCursor() swapCursor()的CursorAdapter

I need some help with my code here, it's driving me nuts. this might be a noob question but I'm quite new to all this SQLite-Database-Cursor-Adapter-ListView-Do-It-Properly-Stuff.

What I have:

In my MainActivity I have a ListView. I use an SQLite database and populate the ListView with a custom adapter extending SimpleCursorAdapter. By clicking on an item in my ActionBar I activate Contextual Action Mode. Everything is working so far.

What I want:

By clicking on a certain icon in my ListView item the according database row should be deleted and the ListView should be refreshed.

My question:

How do I refresh my Cursor and my ListView properly? When I don't use cursor.requery() in my OnClickListener and use cursor = dbm.getIOIOSensorsCursor() instead I get a CursorIndexOutOfBoundsException a few rows below at the line

int state = cursor.getInt(cursor.getColumnIndex(IOIOSensorSchema.STATE));

My app crashes, but after reloading it the database has been deleted and the according ListView item is gone.

I guess the crash must have something to do with _position in get getView method because _position is final. However, when I use cursor.requery() everything works as it should.

BUT... (there's always a but) this method is deprecated and it's documentation says "Don't use this...". I'm a friend of coding properly (I'm still a beginner and want to learn to code the right way and not quick-and-dirty) and want to know how to do this right. I don't know if it's important but I'm testing my app only on my (really fast) Nexus 4. There seem to be no problems with refreshing the Cursor fast enough, but I wonder if it will work on slower devices. In case it's important for you my database will contain about 10-20 rows with about 12 columns. I guess this is a really small database, but as I said in the beginning, this is all very new to me.

Here is the relevant code of my custom adapter:

public class IOIOSensorCursorAdapterCam extends SimpleCursorAdapter
{
static class ViewHolder
{
ImageView stateIV, removeIV;
TextView nameTV, pinNumberTV, feedIDTV, freqTV;
}

private Context ctx;
private Cursor cursor;
private IodDatabaseManager dbm;

public IOIOSensorCursorAdapterCam(Context _context, int _layout,
    Cursor _cursor, String[] _from, int[] _to, int _flags)
{
super(_context, _layout, _cursor, _from, _to, _flags);
ctx = _context;
cursor = _cursor;
dbm = new IodDatabaseManager(_context);
}

@Override
public View getView(final int _position, View _convertView,
    ViewGroup _parent)
{
ViewHolder holder = null;

LayoutInflater inflater = (LayoutInflater) ctx
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

// There is no view at this position, we create a new one. In this case
// by inflating an xml layout.
if (_convertView == null)
{
    // Inflate a layout
    _convertView = inflater.inflate(R.layout.listview_item_sensor_cam,
        null);

    holder = new ViewHolder();
    holder.stateIV = (ImageView) _convertView
        .findViewById(R.id.stateImageView);
    holder.nameTV = (TextView) _convertView
        .findViewById(R.id.sensorNameTextView);
    holder.pinNumberTV = (TextView) _convertView
        .findViewById(R.id.sensorPinNumberTextView);
    holder.feedIDTV = (TextView) _convertView
        .findViewById(R.id.sensorFeedIDTextView);
    holder.freqTV = (TextView) _convertView
        .findViewById(R.id.sensorFrequencyTextView);
    holder.removeIV = (ImageView) _convertView
        .findViewById(R.id.removeImageView);
    _convertView.setTag(holder);
}
// We recycle a View that already exists.
else
{
    holder = (ViewHolder) _convertView.getTag();
}

// Set an OnClickListener to the "Delete Icon"
holder.removeIV.setOnClickListener(new OnClickListener()
{
    @SuppressWarnings("deprecation")
    @Override
    public void onClick(View _view)
    {
    cursor.moveToPosition(_position);

    // Delete sensor from database here
    int sensorID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    // This leads to a "CursorIndexOutOfBoundsException" and cannot
    // be used to refresh the ListView
//      cursor = dbm.getIOIOSensorsCursor();

    // Refresh ListView
    cursor.requery();
    notifyDataSetChanged();
    }
});

cursor.moveToPosition(_position);

if (cursor.getCount() > 0)
{
    int state = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.STATE));

    if (state == 0)
    {
    holder.stateIV.setImageResource(R.drawable.av_play_over_video);
    holder.stateIV.setColorFilter(ctx.getResources().getColor(
        R.color.hint_lighter_gray));
    // _convertView.setAlpha((float) 0.5);
    holder.nameTV.setTextColor(ctx.getResources().getColor(
        R.color.hint_darker_gray));
    }
    else
    {
    holder.stateIV.setImageResource(R.drawable.av_pause_over_video);
    holder.stateIV.setColorFilter(ctx.getResources().getColor(
        android.R.color.holo_green_light));
    // _convertView.setAlpha((float) 1);
    holder.nameTV.setTextColor(ctx.getResources().getColor(
        android.R.color.black));
    }

    // Set the sensor's name to the according TextView
    String sensorName = cursor.getString(cursor
        .getColumnIndex(IOIOSensorSchema.NAME));
    holder.nameTV.setText(sensorName);

    // Set the sensor's pin number to the according TextView
    int pinNumber = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.PIN_NUMBER));
    holder.pinNumberTV.setText("" + pinNumber);

    // Set the sensor's feed ID to the according TextView
    int feedID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.FEED_ID));
    holder.feedIDTV.setText("" + feedID);

    // Set the sensor's frequency to the according TextView
    int frequency = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.FREQUENCY));
    int timeUnit = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.TIME_UNIT));
    String frequencyTextViewText = "";
    switch (timeUnit)
    {
    case IodIOIOSensor.TIME_UNIT_MINUTES:
    frequencyTextViewText = frequency + " min";
    break;
    case IodIOIOSensor.TIME_UNIT_HOURS:
    frequencyTextViewText = frequency + " h";
    break;
    default:
    frequencyTextViewText = frequency + " sec";
    break;
    }
    holder.freqTV.setText(frequencyTextViewText);
}
return _convertView;
}
}

Edit:

Here is my relevant code from the OnCickListener after inplementing the solution:

// Set an OnClickListener to the "Delete Icon"
holder.removeIV.setOnClickListener(new OnClickListener()
{
    @Override
    public void onClick(View _view)
    {
    cursor.moveToPosition(_position);

    // Delete sensor from database here
    int sensorID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    Toast.makeText(ctx, R.string.toast_sensor_deleted,
        Toast.LENGTH_SHORT).show();

    // Refresh ListView
    cursor = dbm.getIOIOSensorsCursor();
    swapCursor(cursor);

    notifyDataSetChanged();
    }
});

解决方案

How do I refresh my Cursor and my ListView properly?

You "refresh [your] Cursor" by running your code again to get the Cursor, using the code you used to create the original Cursor (on a background thread, please). You refresh your ListView by calling changeCursor() or swapCursor() on the CursorAdapter.

这篇关于Android的:如何重新查询光标删除数据库行之后刷新的ListView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆