Android:SQLiteDatabase

时间:2017-05-19 21:11:46

标签: android listview android-sqlite android-arrayadapter android-viewholder

我创建了一个SQLiteDatabase,用于保存用户输入的信息。用户通过Facebook输入他们想要与他人分享的用餐食谱的数据。存储该用户数据,然后在列表视图中显示。这在大多数情况下都可以正常工作,但是当滚动listview以观察更多条目时,会出现nullpointer。我将3种类型的文本信息存储到此数据库中,但我只希望listview显示行的entryID,并在单击该项时显示其余信息。

错误消息:

enter image description here

这是它引用的适配器类:

import android.content.Context;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class RecipeAdapter extends ArrayAdapter {

List list = new ArrayList();

public RecipeAdapter(Context context, int resource) {
    super(context, resource);
}


public void add(Recipe object) {
    list.add(object);
    super.add(object);
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    RecipeHolder recipeHolder;
    if(row == null){

        LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = layoutInflater.inflate(R.layout.display_entry_row,parent,false);
        recipeHolder = new RecipeHolder();
        recipeHolder.tx_id = (TextView)row.findViewById(R.id.t_id);

    }
    else{

        recipeHolder = (RecipeHolder) row.getTag();

    }

    Recipe recipe = (Recipe)getItem(position);

    recipeHolder.tx_id.setText(recipe.getId_entry().toString());

    return row;
}

static class RecipeHolder{

    TextView tx_id;

}
}

这是它所指的行:

recipeHolder.tx_id.setText(recipe.getId_entry().toString());

带有getter和setter的食谱任务:

public class Recipe {

private String id_entry;

public Recipe(String id_entry){

    this.setId_entry(id_entry);

}

public String getId_entry() {
    return id_entry;
}

public void setId_entry(String id_entry) {
    this.id_entry = id_entry;
}
}

如果需要我的数据库本身的后台任务:

 import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ListView;
import android.widget.Toast;


public class BackgroundTask extends AsyncTask<String, Recipe, String> {

Context ctx;
RecipeAdapter mRecipeAdapter;
Activity activity;
ListView listView;
BackgroundTask(Context ctx){
    this.ctx = ctx;
    activity = (Activity)ctx;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {

    String method = params[0];
    DatabaseOperations dbOperations = new DatabaseOperations(ctx);

    //adds information into database
    if (method.equals("add_information")){

        String entry = params[1];
        String ingred = params [2];
        String direc = params [3];
        SQLiteDatabase db = dbOperations.getWritableDatabase();
        dbOperations.putInformation(db, entry, ingred, direc);
        return "One Row Inserted";
    }
    //gets information from database and places inside listview
    else if (method.equals("get_info")){

        listView = (ListView) activity.findViewById(R.id.listVrecipe);
        SQLiteDatabase db = dbOperations.getReadableDatabase();
        Cursor cursor = dbOperations.getInformation(db);
        mRecipeAdapter = new RecipeAdapter(ctx,R.layout.display_entry_row);
        String entry;
        //loops through all row information
        while (cursor.moveToNext()){

            //grabs entry id
            entry = cursor.getString(cursor.getColumnIndex(TableData.TableInfo.EntryID));
            Recipe recipe = new Recipe(entry);
            publishProgress(recipe);

        }
        return "get_info";
    }
    return null;
}

@Override
protected void onProgressUpdate(Recipe... values) {

    mRecipeAdapter.add(values[0]);


}

@Override
protected void onPostExecute(String result) {

    //after execution update listview with new entries
    if(result.equals("get_info")){

        listView.setAdapter(mRecipeAdapter);

    }
    else{

        Toast.makeText(ctx,result, Toast.LENGTH_LONG).show();

    }



}
}

1 个答案:

答案 0 :(得分:1)

根据附件image,它说明您使用适配器NullPointerException方式获取getView()

从我的观点来看,有两种可能性。

1。 RecipeHoldernull,因为您未使用recipeHolder将标记设置为row.setTag(recipeHolder)

2。可能Recipe对象为null

当您使用ArrayAdapter时,最好使用此方法,如下所示:

更新RecipeAdapter,如下所示:

import android.content.Context;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class RecipeAdapter extends ArrayAdapter<Recipe> {


    public RecipeAdapter(Context context, int resource, ArrayList<Recipe> list) {
        super(context, resource, list);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RecipeHolder recipeHolder;

        if(convertView == null){

            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.display_entry_row,parent, false);

            recipeHolder = new RecipeHolder();
            recipeHolder.tx_id = (TextView) convertView.findViewById(R.id.t_id);

            convertView.setTag(recipeHolder);
        }
        else{
            recipeHolder = (RecipeHolder) convertView.getTag();
        }

        Recipe recipe = (Recipe) getItem(position);

        recipeHolder.tx_id.setText(recipe.getId_entry().toString());

        return row;
    }

    static class RecipeHolder {

        TextView tx_id;
    }
}

更新BackgroundTask,如下所示:

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ListView;
import android.widget.Toast;

public class BackgroundTask extends AsyncTask<String, Recipe, String> {

    Context ctx;
    RecipeAdapter mRecipeAdapter;
    Activity activity;
    ListView listView;

    List<Recipe> listRecipe;

    BackgroundTask(Context ctx){
        this.ctx = ctx;
        activity = (Activity)ctx;
        listRecipe = new ArrayList<Recipe>();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {

        String method = params[0];
        DatabaseOperations dbOperations = new DatabaseOperations(ctx);

        //adds information into database
        if (method.equals("add_information")){

            String entry = params[1];
            String ingred = params [2];
            String direc = params [3];
            SQLiteDatabase db = dbOperations.getWritableDatabase();
            dbOperations.putInformation(db, entry, ingred, direc);
            return "One Row Inserted";
        }
        //gets information from database and places inside listview
        else if (method.equals("get_info")){

            listView = (ListView) activity.findViewById(R.id.listVrecipe);
            SQLiteDatabase db = dbOperations.getReadableDatabase();
            Cursor cursor = dbOperations.getInformation(db);

            // Adapter
            mRecipeAdapter = new RecipeAdapter(ctx, R.layout.display_entry_row, listRecipe);
            String entry;

            //loops through all row information
            while (cursor.moveToNext()){

                //grabs entry id
                entry = cursor.getString(cursor.getColumnIndex(TableData.TableInfo.EntryID));
                Recipe recipe = new Recipe(entry);

                // Add recipe to list
                listRecipe.add(recipe);
                mRecipeAdapter.notifyDataSetChanged();

                //publishProgress(recipe);
            }
            return "get_info";
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Recipe... values) {

        //mRecipeAdapter.add(values[0]);
    }

    @Override
    protected void onPostExecute(String result) {

        //after execution update listview with new entries
        if(result.equals("get_info")){
            listView.setAdapter(mRecipeAdapter);
        } else {
            Toast.makeText(ctx,result, Toast.LENGTH_LONG).show();
        }
    }
}

希望这会有所帮助〜