我正在使用SQlite数据库来存储我的listview
数据。
我添加了更改listview项目的机会,通过滑动等删除它们。当我使用IDE运行我的应用程序时,一切正常 - 数据可以删除或更改,但是当我尝试使用手机重新启动它时,我收到此错误:
02-04 22:13:03.276 31682-31682/com.example.jeavie.deadlineyesterday E/InputEventReceiver: Exception dispatching input event.
02-04 22:13:03.276 31682-31682/com.example.jeavie.deadlineyesterday E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
02-04 22:13:03.278 31682-31682/com.example.jeavie.deadlineyesterday E/MessageQueue-JNI: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.jeavie.deadlineyesterday.MainActivity$2.onTouch(MainActivity.java:411)
at android.view.View.dispatchTouchEvent(View.java:11772)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2962)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2643)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
at android.view.View.dispatchPointerEvent(View.java:12015)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.
我的 MainActivity 类:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
public final static int INTENT_REQUEST_CODE = 1;
public final static int INTENT_REQUEST_CODE_TWO = 2;
public static int INTENT_RESULT_CODE = 1;
public static int INTENT_RESULT_CODE_TWO = 2;
public final static int INTENT_EMPTY_CODE = 0;
public static Integer listNumber = 0;
public static Integer dataNumber = 1;
public static Integer editNumber = 1;
//Swiping
private boolean mSwiping = false; // detects if user is swiping on ACTION_UP
private boolean mItemPressed = false; // Detects if user is currently holding down a view
private ListView listView;
DeadlineActivityAdapter deadlineActivityAdapter;
List<DeadlineActivity> list;
String summary, getData, getTime;
DbActivity db;
Cursor fullData;
boolean full;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_drawer);
db = new DbActivity(this);
fullData = db.getAllData();
if (fullData.getCount() > 0){
if (fullData.moveToFirst()) {
list = new ArrayList<>();
do {
String check = fullData.getString(7);
if (check.startsWith("li")){
summary=fullData.getString(2);
getData=fullData.getString(3);
getTime=fullData.getString(4);
String deadline=fullData.getString(5);
String tags=fullData.getString(6);
list.add(new DeadlineActivity(String.valueOf(dataNumber - 1), summary, getData, getTime, deadline,
tags));
full = true;
listNumber++;
}
} while (fullData.moveToNext());
}
}
if (!full) list = new ArrayList<>();
Toolbar toolbar = findViewById(R.id.toolbar_main);
setSupportActionBar(toolbar);
FloatingActionButton addTask = findViewById(R.id.addTask);
addTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, AddTaskActivity.class);
startActivityForResult(intent, INTENT_REQUEST_CODE);
}
});
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.open, R.string.close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.navigation);
navigationView.setNavigationItemSelectedListener(this);
listView = findViewById(R.id.listDeadlines);
TextView emptyText = findViewById(android.R.id.empty);
listView.setEmptyView(emptyText);
deadlineActivityAdapter = new DeadlineActivityAdapter(this, list, mTouchListener);
listView.setAdapter(deadlineActivityAdapter);
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == INTENT_RESULT_CODE){
if(resultCode == INTENT_RESULT_CODE) {
Cursor newDeadline = db.getAllData();
newDeadline.moveToLast();
summary=newDeadline.getString(2);
getData=newDeadline.getString(3);
getTime=newDeadline.getString(4);
String deadline=newDeadline.getString(5);
String tags=newDeadline.getString(6);
list.add(new DeadlineActivity(String.valueOf(dataNumber), summary, getData, getTime, deadline,
tags));
dataNumber++;
deadlineActivityAdapter.notifyDataSetChanged();
super.onActivityResult(requestCode, resultCode, data);
}
}
else if (requestCode == INTENT_RESULT_CODE_TWO){
if (resultCode == INTENT_RESULT_CODE_TWO) {
String a = list.get(editNumber).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
list.remove(Integer.valueOf(id) - 1);
list.add(Integer.valueOf(id) - 1, new DeadlineActivity(id, summary, getData, getTime, deadline, tags));
deadlineActivityAdapter.notifyDataSetChanged();
}
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.toWeek:
startActivity(new Intent(this, WeekActivity.class));
return true;
case R.id.history:
startActivity(new Intent(this, HistoryActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.tags:
startActivity(new Intent(this, TagsActivity.class));
return true;
case R.id.notifications:
// startActivity(new Intent(this, HistoryActivity.class));
return true;
case R.id.info:
// startActivity(new Intent(this, HistoryActivity.class));
return true;
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private View.OnTouchListener mTouchListener = new View.OnTouchListener()
{
float mDownX;
private int mSwipeSlop = -1;
boolean swiped;
@Override
public boolean onTouch(final View v, MotionEvent event) {
if (mSwipeSlop < 0) {
mSwipeSlop = ViewConfiguration.get(MainActivity.this).getScaledTouchSlop();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mItemPressed) return false; // Doesn't allow swiping two items at same time
mItemPressed = true;
mDownX = event.getX();
swiped = false;
break;
case MotionEvent.ACTION_CANCEL:
v.setTranslationX(0);
mItemPressed = false;
break;
case MotionEvent.ACTION_MOVE:
{
float x = event.getX() + v.getTranslationX();
float deltaX = x - mDownX;
float deltaXAbs = Math.abs(deltaX);
if (!mSwiping) {
if (deltaXAbs > mSwipeSlop) {
mSwiping = true; // tells if user is actually swiping or just touching in sloppy manner
listView.requestDisallowInterceptTouchEvent(true);
}
}
if (mSwiping && !swiped) { // Need to make sure the user is both swiping and has not already completed a swipe action (hence mSwiping and swiped)
v.setTranslationX((x - mDownX)); // moves the view as long as the user is swiping and has not already swiped
if (deltaX > v.getWidth() / 3) { // swipe to right
mDownX = x;
swiped = true;
mSwiping = false;
mItemPressed = false;
v.animate().setDuration(300).translationX(v.getWidth()/3);
int i = listView.getPositionForView(v);
String a = list.get(i).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
boolean isInserted = db.updateData(id, id, summary, getData, getTime, deadline, tags, "history");
if (isInserted)
Toast.makeText(getApplicationContext(), "Deadline completed", Toast.LENGTH_SHORT).show();
list.remove(i);
deadlineActivityAdapter.notifyDataSetChanged();
return true;
}
else if (deltaX < -1 * (v.getWidth() / 3)) { // swipe to left
mDownX = x;
swiped = true;
mSwiping = false;
mItemPressed = false;
v.animate().setDuration(300).translationX(-v.getWidth()/3);
int i = listView.getPositionForView(v);
String a = list.get(i).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
boolean isInserted = db.updateData(id, id, summary, getData, getTime, deadline, tags, "history");
if (isInserted)
Toast.makeText(getApplicationContext(), "Deadline completed", Toast.LENGTH_SHORT).show();
list.remove(i);
deadlineActivityAdapter.notifyDataSetChanged();
return true;
}
}
}
break;
case MotionEvent.ACTION_UP: {
if (mSwiping) { // if the user was swiping, don't go to the and just animate the view back into position
v.animate().setDuration(300).translationX(0).withEndAction(new Runnable() {
@Override
public void run() {
mSwiping = false;
mItemPressed = false;
listView.setEnabled(true);
}
});
}
else { // user was not swiping; registers as a click
//set item click "animation"
ColorDrawable[] color = {
new ColorDrawable(getColor(R.color.grey)),
new ColorDrawable(getColor(R.color.dark_dark_grey))
};
TransitionDrawable trans = new TransitionDrawable(color);
v.setBackground(trans);
trans.startTransition(1000); // duration 2 seconds
// Go back to the default background color of Item
ColorDrawable[] color2 = {
new ColorDrawable(getColor(R.color.dark_dark_grey)),
new ColorDrawable(getColor(R.color.the_darkest_grey))
};
TransitionDrawable trans2 = new TransitionDrawable(color2);
v.setBackground(trans2);
trans2.startTransition(1000); // duration 2 seconds
editNumber = listView.getPositionForView(v);
String a = list.get(editNumber).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
Intent intent = new Intent();
intent.putExtra("number", id);
intent.setClass(MainActivity.this, EditTaskActivity.class);
startActivityForResult(intent, INTENT_REQUEST_CODE_TWO);
mItemPressed = false;
listView.setEnabled(true);
return true;
}
}
default:
return false;
}
return true;
}
};
}
我添加了OnTouch方法。
答案 0 :(得分:1)
猜测你可能会对如何处理游标感到困惑。
经常发现被破坏的规则是,除非特别设置为null,否则Cursor永远不会为空。任何检查空Cursor都可能是不必要的。
另外moveToFirst
没有对第一行做某事可能会导致处理问题。
因此,我建议您将getData
方法更改为: -
public Cursor getData(String id) {
SQLiteDatabase db = this.getReadableDatabase();
return dq.query(true,
new String[] { DB_NUMBER, DB_SUMMARY,
DB_DATE, DB_TIME, DB_DEADLINE, DB_TAGS},
DB_ID + "=?",
new String[]{id},
null,null,null,null
);
}
即。只是返回光标,因为null检查没用,moveToFirst很可能导致问题。
在调用 getData
方法的代码中,因为它通过id查找,因此只找到1行: -
Cursor csr = mydbhlpr.getData();
if(csr.moveToFirst) {
//your code to retrieve and act upon the data from the cursor
} else {
//your code, if needed, to handle no row being found.
}
我的猜测是你已经做过类似的事情: -
Cursor csr = mydbhlpr.getData(); // assuming it is not empty and moved to first row
String mydata = csr.getString(whatever_column_offset);
答案 1 :(得分:0)
DatabaseHelper
调用insertData
MainActivity
函数来填充数据库MainActivity
您只是查询数据库中的数据