【问题标题】:SQLite Database to listView?SQLite 数据库到 listView?
【发布时间】:2016-01-17 20:04:59
【问题描述】:

当您单击add 按钮时,我正在尝试从我的数据库中的ITEMS 列中获取数据以显示在Items listView 中。当您单击add 按钮时,它只是将一个项目保存在数据库的列中。我将不胜感激!

主要的 Java 类(New_Recipe

public class New_Recipe extends AppCompatActivity {

Button add,done,display;
EditText Recipe_Name,Recipe_Item,Recipe_Steps;
String search;
WebView webView;
DatabaseHelper databaseHelper;
ListView Items;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new__recipe);
    databaseHelper = new DatabaseHelper(this);
    setTitle("New Recipe");
    add = (Button) findViewById(R.id.button2);
    done = (Button) findViewById(R.id.button);
    Recipe_Name = (EditText) findViewById(R.id.editText);
    Recipe_Item = (EditText) findViewById(R.id.editText2);
    Recipe_Steps = (EditText) findViewById(R.id.editText3);
    webView = (WebView) findViewById(R.id.webView);
    display = (Button) findViewById(R.id.button3);
    Items = (ListView) findViewById(R.id.listView);
    AddData();
    viewAll();

}

public void AddData() {
    done.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
         boolean inserted = databaseHelper.insertData1(Recipe_Name.getText().toString(),
                   Recipe_Steps.getText().toString());
            if (inserted == true)
                Log.d("Database", "Data successfully inserted!");
            else Log.d("Database","Data did not insert!");
        }
    });
    add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean inserted = databaseHelper.insertData2(Recipe_Item.getText().toString());
            if (inserted == true)
                Log.d("Database", "Data successfully inserted!");
         else Log.d("Database","Data did not insert!");
    }
    });
}
public void viewAll() {
    display.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          Cursor res = databaseHelper.getAllData();
            if (res.getCount() == 0) {
                showMessage("Error","No Data found!");
                return;
            }
            StringBuffer stringBuffer = new StringBuffer();
            while (res.moveToNext()) {
                stringBuffer.append("Names :"+res.getString(0)+"\n");
                stringBuffer.append("Items :"+res.getString(1)+"\n");
                stringBuffer.append("Steps :"+res.getString(2)+"\n\n");

            }
            showMessage("Success!",stringBuffer.toString());
        }
    });
}
public void showMessage(String title,String message) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.show();
}

public void onSearch(View v) {
    search = "Recipes";
    webView.loadUrl("https://www.google.com/search?q="+search);
}

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

数据库 Java 类(DatabaseHelper

public class DatabaseHelper extends SQLiteOpenHelper {

public static final String DATABASE_NAME = "Recipes.db";
public static final String TABLE_NAME = " Recipe_Table";
public static final String COL1 = "NAME";
public static final String COL2 = "ITEMS";
public static final String COL3 = "STEPS";


public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, 1);
    Log.d("Database", "Database should be made!");
}


    @Override
    public void onCreate (SQLiteDatabase db){
        db.execSQL("create table " + TABLE_NAME + " (NAME TEXT PRIMARY KEY,ITEMS TEXT,STEPS TEXT)");
        Log.d("Database", "Database should be made!, Again");
    }

    @Override
    public void onUpgrade (SQLiteDatabase db,int oldVersion, int newVersion){
        db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
        Log.d("Database", "Table exists");
        onCreate(db);

    }

    public boolean insertData1(String name,String steps) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL1, name);
        contentValues.put(COL3, steps);

        long result = db.insert(TABLE_NAME,null,contentValues);
        if (result == -1)
            return false;
         else
            return true;

    }
public boolean insertData2(String items) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
   contentValues.put(COL2, items);

    long result = db.insert(TABLE_NAME,null,contentValues);
    if (result == -1)
        return false;
    else
        return true;

}
public Cursor getAllData() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
    return res;
}
public Cursor getItemData() {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res = db.rawQuery("select"+COL2+"from"+TABLE_NAME,null);
    return res;
}
}

【问题讨论】:

    标签: android sqlite listview adapter


    【解决方案1】:

    真正的 Android 方法是使用 ContentProviderCursorAdapter 的组合。

    Android 已经有办法从查询中获取Cursor 并将数据放入ListViewCursorAdapter 类。您只需覆盖 getView() 即可为您的列表创建项目视图。

    以下是自定义 ContentProvider 将为您提供的内容:当您创建内容提供程序 URI 并查询它以获取 Cursor 时,会设置一个 DataObserver,以便当您通过插入/删除/更新数据时ContentProvider 使用该 URI,Cursor 将收到数据已更改的通知,并将重新查询数据。当 Cursor 设置在 CursorAdapter 上时,适配器将看到游标数据已更改并调用 notifyDataSetChanged()

    所以最终结果是,当您添加记录时,您的ListView自动用当前数据刷新。

    有关 Content Providers 的介绍,请参考这篇文章:Content Providers | Android Developers

    【讨论】:

    • 好答案,我还没有尝试过,但我现在会:-)
    • ContentProviders 对于这样的应用程序可能有点重量级,但它们还有其他不错的功能;例如,从 UI 线程执行查询。所以我认为值得研究。
    • 从 UI 线程执行查询,而不是创建异步任务或类似的东西?是这个意思吗?
    【解决方案2】:

    您需要创建一个适配器,列表视图可以从中提取数据。您会将来自 getAllData() 调用的数据传递给适配器,然后列表视图将显示该适配器。

    如果您还没有,您可以创建一个扩展基本适配器的自定义类,正确实现方法,然后您只需要担心数据。

    首先,我总是喜欢构建一个可以存储从数据库检索到的数据的类。一些简单的东西,比如:

    public class ItemObject {
        // Instance variables.
        private String mName, mItem, mStep;
    
        // Constructor.
        public ItemObject(String name, String item, String step) {
            mName = name;
            mItem = item;
            mStep = step;
        }
    
        // Create getters for each item.
        public String getName() { /*...*/ }
        public String getItem() { /*...*/ }
        public String getStep() { /*...*/ }
    }
    

    现在您有了一个可以存储从数据库表中检索到的项目的对象。在调用 getAllData() 后的 while 循环中,您在那里创建您的 ItemObject

    例如:

    List<ItemObject> itemObjectList = new ArrayList<>();
    while (res.moveToNext()) {
        // Extract values from the cursor.
        String name = res.getString(0);
        String item = res.getString(1);
        String step = res.getString(2);
    
        // Create the ItemObject and add it to the list.
        ItemObject item = new ItemObject(name, item, step);
    
        // Add it to the list.
        itemObjectList.add(item);
    }
    

    现在,您将获得可以直接传递给适配器的项目列表。

    public class ItemsListAdapter extends BaseAdapter {
        // Instance variables.
        private Context mContext;
        private List<ItemObject> mItemObjectList;
    
        // Constructor.
        public ItemsListAdapter(Context context, List<itemObjectList> itemObjectList) {
            mContext = context;
            mItemObjectList = itemObjectList;
        }
    
        @Override
        public int getCount() {
            return mItemObjectList.size();
        }
    
        @Override
        public Object getItem(int position) {
            return mItemObjectList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            // Inflate your layout for each row here. I wont include list view 
            // optimization here, as you should look it up, its documentation
            // is readily available.
            LayoutInflater inflater = LayoutInflater.from(mContext);
    
            // Inflate the layout.
            View layout = inflater.inflate(R.layout.<your_list_view_row_layout>, null);
    
            // Reference the views inside the layout that will display each value. (Name, Item, Step);
            TextView nameView = (TextView) layout.findViewById(R.id.<your_text_view_id>);
            // Do this for each view.
    
            // Now retrieve your data from the array list.
            ItemObject item = (ItemObject) getItem(position);
    
            // Now you have your item and the 3 values associated with it.
            // Set the values in the UI.
            nameView.setText(item.getName());
    
            // Return the view.
            return layout;
        }
    
        // Use this method to modify the data in the list view.
        // It's an ArrayList so simply add or remove elements, clear it, etc.
        public List<ItemObject> getAdapterList() {
            return mItemObjectList;
        }
    }
    

    要更新列表视图中的项目,请调用getAdapterList() 并修改返回的ArrayList 中的项目。修改后,您必须通过在适配器本身上调用notifyDataSetChanged() 使列表无效。

    希望这会为您指明正确的方向。

    【讨论】:

    • 感谢您的回答,很抱歉回复晚了。现在我在我的 logcat 中收到一个错误,说 E/ArrayAdapter﹕ You must supply a resource ID for a TextView 我不太清楚为什么我首先要使用文本视图,我想我应该使用 listView ...:p跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 2013-06-02
    • 1970-01-01
    相关资源
    最近更新 更多