带有 BaseAdapter 的 ListView

Posted

技术标签:

【中文标题】带有 BaseAdapter 的 ListView【英文标题】:ListView With BaseAdapter 【发布时间】:2015-11-20 09:19:28 【问题描述】:

我正在学习 BaseAdapter。我有自定义列表视图。我想从数据库中填充列表视图中的数据。我收到空指针错误。这是我的代码。

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;

   

这是我扩展 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);



我有模型课

NameAddress.java

public class NameAddress 
  String NamesDb;
  String AddressDb;

而在我的 row.xml 中只有两个 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_
android:layout_
android:orientation="vertical"
tools:context="com.ashu.customlist.MainActivity" >

<EditText
    android:id="@+id/nameEditText"
    android:layout_
    android:layout_
    android:hint="@string/name"
    android:ems="10" android:inputType="text">

    <requestFocus />
</EditText>

<EditText
    android:id="@+id/addressEditText"
    android:layout_
    android:layout_
    android:hint="@string/address"
    android:ems="10" />

<Button
    android:id="@+id/button1"
    android:layout_
    android:layout_
    android:text="@string/save" />

<ListView
    android:id="@+id/mainList"
    android:layout_
    android:layout_ >
</ListView>
</LinearLayout>

日志

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 ComponentInfocom.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

【问题讨论】:

将类名适配器更改为 myAdapeter 之类的,然后重试...。也发布您的 logcat,以便我们可以调试它 【参考方案1】:

问题

您在活动MainActivity 的变量声明部分初始化DbTools dbTools = new DbTools(this);

解决方案

将此行移至onCreate

DbTools dbTools = new DbTools(this);

此行必须在活动生命周期方法之一中,最好在onCreate 方法中。除非Context 将是null

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

        DbTools dbTools = new DbTools(this);
    

问题

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

这两条线路不需要同时调用。

解决方案

    第一次设置适配器时使用mainList.setAdapter(adpter);

    并在您的数据集更改时调用adpter.notifyDataSetChanged();

问题

您也在变量声明部分的Adapter 类中初始化以下行。

DbTools dbTools = new DbTools(context);

由于上下文变量为空,你不能初始化它。

构造函数中的另一个问题是您将空result 保存到参数rslt。其实应该是另一种方式。

解决方案

像这样更新适配器构造函数。

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

也不需要在getView方法中初始化DbTools

【讨论】:

现在我收到无法启动活动组件信息的错误 你能发布你的异常日志吗 请查看编辑后的答案。在您的适配器的构造函数被窃听 是的!完成。非常感谢 :) 这真是个愚蠢的错误。 然后接受对您有帮助的答案。以便其他用户发现它有用【参考方案2】:

更改它,因为您正在访问变量上下文而不分配任何值..

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;


【讨论】:

请在您的回答中添加一些解释 您正在使用空上下文而不分配任何值。

以上是关于带有 BaseAdapter 的 ListView的主要内容,如果未能解决你的问题,请参考以下文章

带有 BaseAdapter 的 Android ListView 内的 ImageButton

ListView 不显示带有 BaseAdapter 的 ImageButton

如何在填充了 BaseAdapter 的 Fragment 中刷新 ListView?

使用带有自定义 baseadapter 的 arraylist 错误地删除列表视图项位置

在使用Baseadapter的Listview中,Android Plus和Minus按钮无法正常工作

如何将数据添加到 listView 的自定义 BaseAdapter - Android