0

나는 사용자 입력으로부터 정보를 저장하는 SQLiteDatabase를 만들었다. 사용자는 페이스 북을 통해 다른 사람들과 공유하고 싶은 식사에 대한 자신의 요리법에 관한 데이터를 입력합니다. 이 사용자 데이터는 저장되고 목록보기 내에 표시됩니다. 대부분의 경우 잘 작동하지만 listview를 스크롤하여 더 많은 항목을 관찰하면 nullpointer가 발생합니다. 이 데이터베이스에 3 가지 유형의 텍스트 정보를 저장하지만 목록보기에서 행의 entryID 만 표시하고 항목을 클릭하면 나머지 정보가 표시되기를 원합니다.안드로이드 : SQLiteDatabase

오류 메시지가 :

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

:

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; 

} 
} 

그것을 참조하는 라인 :

enter image description here

이것은 참조하는 어댑터 클래스입니다 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; 
} 
} 

그리고 데이터베이스 자체 내 백그라운드 작업을 필요한 경우 : 당신의 부착 image, 그 상태 당으로

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(); 

    } 



} 
} 
+0

** RecipeAdpater **의'getView' ** 메소드에서 else 절을 ​​사용하면 ** TextView **의 ID가 확보되지 않을 수 있습니다. Else 절 내에 ** recipeHolder.tx_id = (TextView) row.findViewById (R.id.t_id); **를 추가하거나 두 시나리오에서 사용되도록 교대로 이동하십시오. Else 절 다음에 TextView의 텍스트가 설정되기 전에. – MikeT

+1

'row.setTag (recipeHolder)'가 보이지 않습니다. –

+0

고맙습니다. 태그를 설정하지 않아서 문제가 해결되었습니다. –

답변

1

당신이 당신의 어댑터 getView() 방법에 NullPointerException을 얻고있다.

제 생각에는 두 가지 가능성이 있습니다. 당신이 row.setTag(recipeHolder)를 사용하여 recipeHolder에 태그를 설정하지 않은으로

1.RecipeHoldernull입니다.

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(); 
     } 
    } 
} 

희망 하시겠습니까? lp ~

+0

방금 ​​row.setTag (recipeHolder)를 추가했습니다. RecipeAdapter에있는 다른 것들이 나에게 도움이 되었다면 해결책이 아닌가? –

+0

예 해결책입니다. 또한 ArrayAdapter를 사용할 때 가장 좋은 방법을 추가했습니다. – FAT

+0

감사합니다. 매우 유용합니다. –