ListView With BaseAdapter

社会主义新天地 提交于 2019-12-12 06:08:11

问题


I am learning BaseAdapter. I have custom listview. I want to fill data in listview from database. I am getting error of Null Pointer. Here is my code.

DbTools.java

public class DbTools extends SQLiteOpenHelper {

    public DbTools(Context context) {
         super(context, "local.db", null, 1);

}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table ashu(Name varchar, address varchar)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("Drop Table if Exists ashu");
    onCreate(db);
}

public void InsertDb(String Name,String address) {

    SQLiteDatabase db = getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put("Name", Name);
    cv.put("address", address);
    db.insert("ashu", null, cv);
    db.close();
}

public ArrayList<NameAddress> getAllData(){
    ArrayList<NameAddress> dataFromDb = new ArrayList<NameAddress>();
    String SQL = "Select Name, address from ashu";
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(SQL, null);
    if (cursor.moveToFirst()){
        do{
            NameAddress na = new NameAddress();
            na.NamesDb = cursor.getString(0).toString();
            na.AddressDb = cursor.getString(1).toString();
            dataFromDb.add(na);             
        } while(cursor.moveToNext());
    }
    return dataFromDb;

   }
}

This is my Adapter class in which I extended BaseAdapter

Adapter.java

public class Adapter extends BaseAdapter{

 public ArrayList<NameAddress> result;
ListView lv;
private Context context;
DbTools dbTools = new DbTools(context);
private LayoutInflater inflater = null;


public Adapter(Context context,ArrayList<NameAddress> rslt){
    rslt=result;
    this.context=context;
    inflater =  (LayoutInflater)(this.context).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}


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

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

@Override
public long getItemId(int position) {   
    return position;
}

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

    final NameAddress tmpData = result.get(position);
    Holder h = new Holder();
    DbTools dbTools = new DbTools(context);

    View rootView;
    rootView = inflater.inflate(R.layout.row, null);
    h.textView1 = (TextView) rootView.findViewById(R.id.mainText);
    h.textView2 = (TextView) rootView.findViewById(R.id.subText);
    h.textView1.setText(tmpData.NamesDb);
    h.textView2.setText(tmpData.AddressDb);

    return rootView;
}

class Holder{   
    public TextView textView1, textView2;
}
}

MainActivity.java

public class MainActivity extends Activity {

ListView mainList;
Button save;
EditText name,address;
DbTools dbTools = new DbTools(this);
ArrayList<NameAddress> addList;
private Adapter adpter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mainList = (ListView)findViewById(R.id.mainList);
    save = (Button)findViewById(R.id.button1);
    name = (EditText)findViewById(R.id.nameEditText);
    address = (EditText)findViewById(R.id.addressEditText);

    save.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            String tempName = name.getText().toString();
            String tempAdd = address.getText().toString();
            dbTools.InsertDb(tempName, tempAdd);

            Toast.makeText(getApplicationContext(), "Added Successfully", Toast.LENGTH_SHORT).show();
            name.setText("");
            address.setText("");

        }
    });

    addList = new ArrayList<NameAddress>();
    addList = dbTools.getAllData();
    adpter = new Adapter(this, addList);
    adpter.notifyDataSetChanged();
    mainList.setAdapter(adpter);

}
}

And I have model class

NameAddress.java

public class NameAddress {
  String NamesDb;
  String AddressDb;
}

And In my row.xml there are only two textviews

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.ashu.customlist.MainActivity" >

<EditText
    android:id="@+id/nameEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/name"
    android:ems="10" android:inputType="text">

    <requestFocus />
</EditText>

<EditText
    android:id="@+id/addressEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/address"
    android:ems="10" />

<Button
    android:id="@+id/button1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/save" />

<ListView
    android:id="@+id/mainList"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>
</LinearLayout>

LOG

08-26 17:12:30.874: W/dalvikvm(19002): threadid=1: thread exiting with uncaught exception (group=0x41ee3d88)
08-26 17:12:30.874: E/AndroidRuntime(19002): Exception
08-26 17:12:30.874: E/AndroidRuntime(19002): FATAL EXCEPTION: main
08-26 17:12:30.874: E/AndroidRuntime(19002): Process: com.ashu.customlist, PID: 19002
08-26 17:12:30.874: E/AndroidRuntime(19002): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ashu.customlist/com.ashu.customlist.MainActivity}: java.lang.NullPointerException
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2237)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2286)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread.access$800(ActivityThread.java:145)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.os.Handler.dispatchMessage(Handler.java:102)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.os.Looper.loop(Looper.java:136)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread.main(ActivityThread.java:5127)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at java.lang.reflect.Method.invokeNative(Native Method)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at java.lang.reflect.Method.invoke(Method.java:515)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at dalvik.system.NativeStart.main(Native Method)
08-26 17:12:30.874: E/AndroidRuntime(19002): Caused by: java.lang.NullPointerException
08-26 17:12:30.874: E/AndroidRuntime(19002):    at com.ashu.customlist.Adapter.getCount(Adapter.java:31)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.widget.ListView.setAdapter(ListView.java:480)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at com.ashu.customlist.MainActivity.onCreate(MainActivity.java:55)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.Activity.performCreate(Activity.java:5231)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-26 17:12:30.874: E/AndroidRuntime(19002):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2201)
08-26 17:12:30.874: E/AndroidRuntime(19002):    ... 11 more

回答1:


ISSUE

You are initializing DbTools dbTools = new DbTools(this); in variable declaration portion of your activity MainActivity.

SOLUTION

Move this line to onCreate

DbTools dbTools = new DbTools(this);

This line has to be inside one of the activity lifecycle methods, preferably in onCreate method. Unless the Context will be null

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DbTools dbTools = new DbTools(this);
    }

ISSUE

adpter.notifyDataSetChanged();
mainList.setAdapter(adpter);

Both of these lines are not required to call at a time.

SOLUTION

  1. Use this mainList.setAdapter(adpter); the first time you are setting your adapter.

  2. And call adpter.notifyDataSetChanged(); when your dataset is changed.

ISSUE

You are initializing the below line also in your Adapter class at the variable declaration portion.

DbTools dbTools = new DbTools(context);

As the context variable is null you cant initialize this.

Another problem in the constructor is that you are saving the null result to the parameter rslt. Actually it should be in the other way.

SOLUTION

Update the adapter constructor like this.

DbTools dbTools;
public Adapter(Context context,ArrayList<NameAddress> rslt){
    result = rslt; //this line is swapped
    this.context=context;
    dbTools = new DbTools(context);
    inflater =  (LayoutInflater)(this.context).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

Also no need to initialize DbTools in getView method




回答2:


change this with because you are accessing a variable context without assigning any value..

public class Adapter extends BaseAdapter {

public ArrayList<NameAddress> result;
ListView lv;
private Context context;
DbTools dbTools;
private LayoutInflater inflater = null;

public Adapter(Context context, ArrayList<NameAddress> rslt) {
    result = rslt;
    this.context = context;
    dbTools = new DbTools(context);
    inflater = (LayoutInflater) (this.context)
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

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

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

@Override
public long getItemId(int position) {
    return position;
}

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

    final NameAddress tmpData = result.get(position);
    Holder h = new Holder();
    DbTools dbTools = new DbTools(context);

    View rootView;
    rootView = inflater.inflate(R.layout.row, null);
    h.textView1 = (TextView) rootView.findViewById(R.id.mainText);
    h.textView2 = (TextView) rootView.findViewById(R.id.subText);
    h.textView1.setText(tmpData.NamesDb);
    h.textView2.setText(tmpData.AddressDb);

    return rootView;
}

class Holder {
    public TextView textView1, textView2;
}
}


来源:https://stackoverflow.com/questions/32224855/listview-with-baseadapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!