我正在使用Mimir的Android教程#10,关于在列表中显示预先填充的数据库中的数据。在他们的数据库中,它们有四列,即:(1)ingredient_description,(2)in_stock,(3)_id和(4)ingredient_name。但是,在其列表中,它们仅显示来自ingredient_name列的数据。例如,他们的列表看起来像这样......
冰
水
等
但我要做的是连续显示所有四列的数据,如此......
冰
描述:冷冻水
ID:1
有货:是的
水
描述:H2O
ID:2
有货:是的
等
本教程使用bindView和newView,并根据他们的评论,“这使我们的代码更清晰,并且是更好的方法。”
我花了很多时间研究这个问题,但我还没弄清楚如何从数据库中获取这三个额外的列以显示在行中。以下是原始代码以及我所做的一些更改(我的更改在注释中注明* * *)。
我知道我仍然缺少某些东西,但那就是我被困住的地方。有人可以告知缺少什么,以显示这三个额外列中的数据?如果可能的话,请告诉我具体缺少什么/如何修复而不是指向我的教程(我已经看了很多,不幸的是,没有什么能够回答我的问题)。还请记住,示例代码使用bindView和newView,因此需要使用它。非常感谢您的帮助。
package com.mimirsoft.tutorial10;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;
class IngredientHelper extends SQLiteOpenHelper {
//we declare a bunch of useful constants
//the should be pretty obvious what they are!
private static final String DATABASE_PATH = "/data/data/com.mimirsoft.tutorial10/databases/";
private static final String DATABASE_NAME="ingredients.db";
private static final int SCHEMA_VERSION=1;
public static final String TABLE_NAME = "Ingredients";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_TITLE = "ingredient_name";
//* * * MY ADD * * *
public static final String COLUMN_TITLE2 = "ingredient_description";
//* * * MY ADD * * *
public static final String COLUMN_TITLE3 = "in_stock";
public SQLiteDatabase dbSqlite;
private final Context myContext;
public IngredientHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
this.myContext = context;
// check if exists and copy database from resource
//createDB();
}
@Override
public void onCreate(SQLiteDatabase db) {
// check if exists and copy database from resource
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void createDatabase() {
createDB();
}
private void createDB() {
boolean dbExist = DBExists();
if (!dbExist) {
//By calling this method we create an empty database into the default system location
//We need this so we can overwrite that database with our database.
this.getReadableDatabase();
//now we copy the database we included!
copyDBFromResource();
}
}
private boolean DBExists() {
SQLiteDatabase db = null;
try {
String databasePath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null ? true : false;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outStream = null;
String dbFilePath = DATABASE_PATH + DATABASE_NAME;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
outStream = new FileOutputStream(dbFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
outStream.flush();
outStream.close();
inputStream.close();
} catch (IOException e) {
throw new Error("Problem copying database from resource file.");
}
}
public void openDataBase() throws SQLException {
String myPath = DATABASE_PATH + DATABASE_NAME;
dbSqlite = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if (dbSqlite != null)
{
dbSqlite.close();
}
super.close();
}
public Cursor getCursor() {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_NAME);
// * * * MY CHANGE - CHANGED FROM... * * *
//String[] asColumnsToReturn = new String[] { COLUMN_ID, COLUMN_TITLE};
//* * * TO... * * *
//String[] asColumnsToReturn = new String[] { COLUMN_ID, COLUMN_TITLE, COLUMN_TITLE2, COLUMN_TITLE3};
//make sure you get your search by string pass correctly!
Cursor mCursor = queryBuilder.query(dbSqlite, asColumnsToReturn, null,
null, null, null, "ingredient_name ASC");
return mCursor;
}
public String getName(Cursor c) {
return(c.getString(1));
}
}
和...
package com.mimirsoft.tutorial10;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
//This tutorial introduces the CursorAdaptor, explains how it is different
//from the Array Adapter, and also introduces the database functionality.
//We will build a ListView from a Database of cocktail Ingredients
public class Tutorial10 extends Activity {
private IngredientHelper dbIngredientHelper = null;
private Cursor ourCursor = null;
private IngredientAdapter adapter=null;
public void onCreate(Bundle savedInstanceState) {
try
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//this is our ListView element, obtained by id from our XML layout
ListView myListView = (ListView)findViewById(R.id.myListView);
//create our database Helper
dbIngredientHelper=new IngredientHelper(this);
//we call the create right after initializing the helper, just in case
//they have never run the app before
dbIngredientHelper.createDatabase();
//
//open the database!! Our helper now has a SQLiteDatabase database object
dbIngredientHelper.openDataBase();
//get our cursor. A cursor is a pointer to a dataset, in this case
//a set of results from a database query
ourCursor=dbIngredientHelper.getCursor();
//tell android to start managing the cursor,
//we do this just incase our activity is interrupted or ends, we want the activity
//to close and deactivate the cursor, as needed
startManagingCursor(ourCursor);
//create our adapter
adapter=new IngredientAdapter(ourCursor);
//set the adapter!!!
myListView.setAdapter(adapter);
}
catch (Exception e)
{
// this is the line of code that sends a real error message to the log
Log.e("ERROR", "ERROR IN CODE: " + e.toString());
// this is the line that prints out the location in
// the code where the error occurred.
e.printStackTrace();
}
}
class IngredientAdapter extends CursorAdapter {
IngredientAdapter(Cursor c) {
super(Tutorial10.this, c);
}
@Override
//this is a CusorAdapter
//instead of Using a getView and if(row==null)
// we use bindView and newView calls
//we can get away with this because CursorAdapters have
//a default implementation of getView that calls bindView and newView
//as needed. This makes our code a bit cleaner, and is the better way to
//do this.
public void bindView(View row, Context ctxt,
Cursor c) {
IngredientHolder holder=(IngredientHolder)row.getTag();
holder.populateFrom(c, dbIngredientHelper);
}
@Override
public View newView(Context ctxt, Cursor c,
ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row, parent, false);
IngredientHolder holder=new IngredientHolder(row);
row.setTag(holder);
return(row);
}
}
static class IngredientHolder {
private TextView name=null;
IngredientHolder(View row) {
name=(TextView)row.findViewById(R.id.ingredientText);
}
void populateFrom(Cursor c, IngredientHelper r) {
name.setText(r.getName(c));
}
}
}
答案 0 :(得分:0)
简单的方法是,您可以在字符串中每行的末尾添加换行符。这会打破你想要的字符串。这样做的不利之处在于你无法分别为每一行设置样式。
更好的方法是创建一个布局并将每个字符串添加为文本视图。 Android API演示中有一个示例,即Views / Lists / 4。 ListAdapter。因此,将其添加到您的设备或在模拟器上运行它。 包名是com.example.android.apis.view,类是List4.java。
这是API示例中的子类。
/**
* We will use a SpeechView to display each speech. It's just a LinearLayout
* with two text fields.
*
*/
private class SpeechView extends LinearLayout {
public SpeechView(Context context, String title, String words) {
super(context);
this.setOrientation(VERTICAL);
// Here we build the child views in code. They could also have
// been specified in an XML file.
mTitle = new TextView(context);
mTitle.setText(title);
addView(mTitle, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
mDialogue = new TextView(context);
mDialogue.setText(words);
addView(mDialogue, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
答案 1 :(得分:0)
我会尝试类似的东西。传递光标并使用整数选择所需的列,并将数据保存到变量中。
private void getName(c){
name.setText(c.getString(0)
name2.setText(c.getString(1)
name3.setText(c.getString(2)
name4.setText(c.getString(3)
}
然后只需在布局中添加更多文本视图,并使用db中的字符串设置文本。