2015-01-09 3 views
1

Это может оказаться как хромой вопрос, но я новичок и, похоже, не понимаю поведение моего приложения.идентификаторы строк sqlite, не соответствующие списку - ANDROID

У меня есть база данных SQLite и вид списка в основной деятельности. В представлении списка я отображаю список № (идентификатор строки) и другие данные. и при нажатии на элемент списка открывается новое действие, которое отображает детали в текстовом виде и имеет 2 кнопки изображения для удаления и синхронизации.

Приложение работает нормально, пока я не удалю запись.

Как только я удаляю любую запись, идентификатор строки в списке не обновляет номер строки. (если я удаляю первую строку, строка сверху показывает 2 (должно быть 1, так как это новая первая строка)).

Однако, когда я показываю детали записи, это получается правильно. (второй элемент в списке показывает номер строки 2)

Также, когда я нажимаю, нажмите элемент в представлении списка, положение которого совпадает с положением, которое я удалил ранее, когда приложение сработает (предположим, что я удаляю первую запись, после этого каждый раз, когда я нажимаю на первый элемент в виде списка, чтобы отобразить его сбои приложения)

Я получаю ошибку на приложение аварии:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aakashmaroti.fillup/com.example.aakashmaroti.fillup.DisplayDetails}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 

Моя основная деятельность

package com.example.aakashmaroti.fillup; 

import android.app.Dialog; 
import android.content.Context; 
import android.content.Intent; 
import android.content.res.Resources; 
import android.database.Cursor; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.BaseAdapter; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 
import android.widget.TextView; 
import android.widget.Toast; 
import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.List; 


public class StartScreen extends ActionBarActivity implements View.OnClickListener { 


    FavoriteList favList = new FavoriteList(); 

    TextView rid,ts,sd; 
    ListView lv; 
    Context context=this; 
    Find db=new Find(this); 
    List<FavoriteList> favoriteList; 
    LinearLayout layout; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_start_screen); 
     Button b = (Button) findViewById(R.id.AddButton); 
     b.setOnClickListener(this); 
     lv = (ListView) findViewById(R.id.listview); 
     try 
     { 
      populateListViewFromDatabase(); 
     } catch (Exception e) 
     { 
      Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show(); 
      e.printStackTrace(); 
     } 

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


    } 


    @Override 
    public void onResume() 
    { 
     super.onResume(); 
     try 
     { 
      populateListViewFromDatabase(); 
     } catch (Exception e) 
     { 
      Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show(); 
      e.printStackTrace(); 
     } 

    } 

    @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_start_screen, 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); 
    } 

    @Override 
    public void onClick(View v) { 

     switch (v.getId()) 
     { 
      case R.id.AddButton: 
       startActivity(new Intent(this,Form.class)); 
       break; 

      default: break; 
     } 
    } 

    public void populateListViewFromDatabase()throws Exception 
    { 
     Find info=new Find(this); 
     try 
     { 
      info.open(); 
      SimpleCursorAdapter myCursorAdapter; 
      myCursorAdapter = info.listUp(); 
      lv.setAdapter(myCursorAdapter); 
      info.close(); 

     } catch (SQLException e) 
     { 
      e.printStackTrace(); 
      Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show(); 
     } 
    } 
    public void showsDialog(int pos) 
    { 

     pos++; 
     String s = ""; 
     s += pos; 
     Intent i = new Intent(getApplicationContext(), DisplayDetails.class); 
     i.putExtra("position", s); 
     startActivity(i); 

     try 
     { 
      populateListViewFromDatabase(); 
     } catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

} 

SQLite база данных управляющий класс

package com.example.aakashmaroti.fillup; 

import android.app.Dialog; 
import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.graphics.Bitmap; 
import android.graphics.Color; 
import android.view.View; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.sql.SQLException; 
import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by Aakash Maroti on 28-Dec-14. 
*/ 
public class Find 
{ 
    public static final String KEY_ROWID = "_id"; 
    public static final String KEY_TIMESTAMP= "time_stamp"; 
    public static final String KEY_IS_SYNCED = "sync"; 
    public static final String KEY_NameOfCompany="name_of_company"; 



    private static final String DATABASE_NAME = "FillUpFormsDB"; 
    private static final String DATABASE_TABLE = "FillUpFormsTable"; 
    private static final int DATABASE_VERSION = 1; 

    private DbHelper ourHelper; 
    private final Context ourContext; 
    private SQLiteDatabase ourDatabase; 




    private static class DbHelper extends SQLiteOpenHelper 
    { 

     public DbHelper(Context context) 
     { 
      super(context,DATABASE_NAME,null,DATABASE_VERSION); 
     } 



     @Override 
     public void onCreate(SQLiteDatabase db) 
     { 
      db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + 
        KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
          KEY_IS_SYNCED +" TEXT NOT NULL, " + 
          KEY_TIMESTAMP +" TEXT NOT NULL, " + 
          KEY_NameOfCompany+" TEXT NOT NULL);" 
      ); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
     { 
      db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE); 
      onCreate(db); 
     }  

    } 


    public Find(Context c) 
    { 
     ourContext = c; 
    } 

    public Find open()throws SQLException 
    { 
     ourHelper = new DbHelper(ourContext); 
     ourDatabase=ourHelper.getWritableDatabase(); 
     return this; 
    } 

    public void close() 
    { 
     ourHelper.close(); 
    } 


    public long createEntry(String isSynced, String timeStamp, String nameOfCompany) 
    { 
     ContentValues cv=new ContentValues(); 
     cv.put(KEY_IS_SYNCED,isSynced); 
     cv.put(KEY_TIMESTAMP,timeStamp); 
     cv.put(KEY_NameOfCompany,nameOfCompany);   

     return ourDatabase.insert(DATABASE_TABLE,null,cv); 

    } 

    public SimpleCursorAdapter listUp() 
    { 

     String columns[]=new String[]{KEY_ROWID,KEY_TIMESTAMP,KEY_IS_SYNCED}; 
     Cursor c= ourDatabase.query(DATABASE_TABLE,columns,null,null,null,null,null); 
     int toViewIDs[] = new int[]{R.id.rowno,R.id.timestamp,R.id.syncdetails}; 
     SimpleCursorAdapter CursorAdapter; 
     CursorAdapter = new SimpleCursorAdapter(ourContext,R.layout.design_row,c,columns,toViewIDs,0); 
     return CursorAdapter; 
    } 

    public String getDetails(long row) 
    { 
     String columns[]=new String[] {KEY_ROWID, KEY_IS_SYNCED, KEY_TIMESTAMP,KEY_NameOfCompany}; 
     String result="";   
     Cursor c= ourDatabase.query(DATABASE_TABLE,columns,KEY_ROWID+"="+row,null,null,null,null); 
     if(c!=null) 
     { 
      String r; 
      c.moveToFirst(); 
      r="\nRecord No. : "+c.getString(0)+"\n\nSync Status:"+c.getString(1)+"\n\nTime of Creation:\n"+c.getString(2)+"\n\nName of Company:\n"+c.getString(3); 
      return r; 
     } 

     return result; 
    } 

    public void DeleteRow(int pos) 
    { 
     ourDatabase.delete(DATABASE_TABLE,KEY_ROWID+"="+pos,null); 
    } 
} 

класс для новой деятельности, которая показывает результат.

package com.example.aakashmaroti.fillup; 

import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ImageButton; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.sql.SQLException; 


public class DisplayDetails extends ActionBarActivity implements View.OnClickListener 

{ 

    ImageButton ibSync; 
    ImageButton ibDelete; 
    TextView DispDetails; 
    int pos; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     Bundle extras = getIntent().getExtras(); 

     String value="1"; 
     if (extras != null) { 
      value = extras.getString("position"); 
     } 
     pos=Integer.parseInt(value); 
     setContentView(R.layout.activity_display_details); 
     ibSync=(ImageButton)findViewById(R.id.imageButtonSync); 
     ibDelete=(ImageButton)findViewById(R.id.imageButtonDelete); 
     DispDetails = (TextView)findViewById(R.id.textViewDisplayDetails); 
     String s=""; 

     ibSync.setOnClickListener(this); 
     ibDelete.setOnClickListener(this); 

     Find info1=new Find(this); 
     try 
     { 
      info1.open(); 
      s=info1.getDetails(pos); 
      info1.close(); 

     } catch (SQLException e) 
     { 
      e.printStackTrace(); 
      Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show(); 
     } 
     DispDetails.setText(s); 

    } 


    @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_display_details, 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); 
    } 

    @Override 
    public void onClick(View v) 
    { 
     if(v.getId()==R.id.imageButtonSync) 
     { 
      Toast.makeText(getApplicationContext(), "This functionality has not yet been added", Toast.LENGTH_LONG).show(); 
     } 
     if(v.getId()==R.id.imageButtonDelete) 
     { Find info1=new Find(this); 
      try 
      { 
       info1.open(); 
       info1.DeleteRow(pos); 
       info1.close(); 

      } catch (SQLException e) 
      { 
       e.printStackTrace(); 
       Toast.makeText(getApplicationContext(), "Oops there has been an error "+e.toString()+"", Toast.LENGTH_LONG).show(); 
      } 


      Toast.makeText(getApplicationContext(), "This record has been successfully deleted", Toast.LENGTH_LONG).show(); 
      cancel(); 
     } 
    } 

    public void cancel() 
    { 
     this.finish(); 
     return; 
    } 
} 

Xml файл из одной строки в ListView

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="50dp" 
     android:text="" 
     android:textStyle="bold" 
     android:clickable="true" 
     android:id="@+id/rowno"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="50dp" 
     android:textAppearance="?android:attr/textAppearanceMedium" 
     android:text="" 
     android:clickable="true" 
     android:id="@+id/timestamp"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="50dp" 
     android:textStyle="bold" 
     android:text="" 
     android:clickable="true" 
     android:id="@+id/syncdetails"/> 

</LinearLayout> 

Любая помощь будет принята с благодарностью.

Заранее спасибо.

ответ

2

Потому что вы передаете позицию позиции списка, это должен быть идентификатор строки базы данных.

Изменить

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
{ 
    showsDialog(position); 
} 

в

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
{ 
    TextView pos = (TextView) view.findViewById(R.id.rowno); 
    showsDialog(pos.getText().toString()); 
} 

Также вы сказали

Once I delete any entry the row id on the listview doesn't seem to update the row number. (if i delete the first row, the row on top shows 2(should be 1, as it is the new first row)). 

Но это не так, потому что это строка идентификатор базы данных не позиция в виде списка.

+0

большое спасибо! Оно работало завораживающе! , а также есть способ показать позицию позиции вместо идентификатора строки? , поскольку удаление идентификатора строки создает ошибку. Еще раз спасибо! –

+0

Если вы хотите показать позицию позиции listview, а не идентификатор строки, то, думаю, вам придется использовать пользовательский адаптер. – Rohit5k2

-1

Вы используете только свой Курсор в onResume или onCreate. Таким образом, ваш курсор остается таким же, хотя данные изменяются. Изучите класс LoaderManager.

Смежные вопросы