setAdapter 在片段 Android 中不起作用
setAdapter does not work in fragment Android
我在 Activity
中使用了相同的代码并且它有效。但同样的事情在 Fragment
中不起作用。我已经放置了一些测试来检查数据库是否正确创建并发现 cursor
充满了数据。
代码如下:
public class Db_fragment extends Fragment {
View view;
ListView listView;
Db_listView_Adapter db_listView_adapter;
public Db_fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
enterData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TableFoodMacros.FoodMacros.FOOD_NAME,foodName.getText().toString());
long newRowId ;
newRowId = myDb.insert(TableFoodMacros.FoodMacros.TABLE_NAME,null,contentValues);
Log.e("TEST1","TEST INSERT " + String.valueOf(newRowId));
}
});
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
}
}
应用程序在此行崩溃:
listView.setAdapter(db_listView_adapter);
您需要从 showData
的 onClickListener
中删除 dbView
的 findViewById
并将其放在 onCreateView
中。
所以删除以下内容。
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// ... Remove the following code segment from here.
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
将代码段放入 onCreateView
函数中。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
// Place the code segment here
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
return view;
}
它在您的 Activity
中有效,因为您没有在返回的 View
中找到 ListView
ID。设置 Activity
的内容视图后,您可以将 findViewById
放置在任何地方,它会完美地找到关联的布局参考。
在 Fragment
的情况下,如您所见 onCreateView
函数 returns 一个 View
对象作为 View
的引用,它被膨胀了。所以你需要在 View
中找到你的 ListView
。这就是为什么您需要放置 view.findViewById
来搜索 ListView
中被膨胀的 View
的引用 ID。
当您将 listView = (ListView) view.findViewById(R.id.dbView);
放入 showData.setOnClickListener
中时,它会获取按钮 showData
的引用并尝试在 [=38] 中找到 dbView
=] 导致错误的视图。
因此有必要在 onCreateView
中获取列表的引用并在那里设置适配器。当 cursor
填满数据时,您可以轻松地调用 notifyDatasetChanged()
重新加载列表。
顺便说一下,您也可以将代码段放入 onViewCreated
函数中,因为您可以从那里毫无问题地获取 showData
按钮的引用。所以你甚至可以把代码段放在那里。
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
// You can place the code segment here too
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
// ... Other code goes here.
}
您可以像这样修改 showData.setOnClickListener
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
// Call notifyDatasetChanged when the cursor is filled with data to load the list.
db_listView_adapter.notifyDatasetChanged();
}
});
我在 Activity
中使用了相同的代码并且它有效。但同样的事情在 Fragment
中不起作用。我已经放置了一些测试来检查数据库是否正确创建并发现 cursor
充满了数据。
代码如下:
public class Db_fragment extends Fragment {
View view;
ListView listView;
Db_listView_Adapter db_listView_adapter;
public Db_fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
enterData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TableFoodMacros.FoodMacros.FOOD_NAME,foodName.getText().toString());
long newRowId ;
newRowId = myDb.insert(TableFoodMacros.FoodMacros.TABLE_NAME,null,contentValues);
Log.e("TEST1","TEST INSERT " + String.valueOf(newRowId));
}
});
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
}
}
应用程序在此行崩溃:
listView.setAdapter(db_listView_adapter);
您需要从 showData
的 onClickListener
中删除 dbView
的 findViewById
并将其放在 onCreateView
中。
所以删除以下内容。
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// ... Remove the following code segment from here.
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
将代码段放入 onCreateView
函数中。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
// Place the code segment here
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
return view;
}
它在您的 Activity
中有效,因为您没有在返回的 View
中找到 ListView
ID。设置 Activity
的内容视图后,您可以将 findViewById
放置在任何地方,它会完美地找到关联的布局参考。
在 Fragment
的情况下,如您所见 onCreateView
函数 returns 一个 View
对象作为 View
的引用,它被膨胀了。所以你需要在 View
中找到你的 ListView
。这就是为什么您需要放置 view.findViewById
来搜索 ListView
中被膨胀的 View
的引用 ID。
当您将 listView = (ListView) view.findViewById(R.id.dbView);
放入 showData.setOnClickListener
中时,它会获取按钮 showData
的引用并尝试在 [=38] 中找到 dbView
=] 导致错误的视图。
因此有必要在 onCreateView
中获取列表的引用并在那里设置适配器。当 cursor
填满数据时,您可以轻松地调用 notifyDatasetChanged()
重新加载列表。
顺便说一下,您也可以将代码段放入 onViewCreated
函数中,因为您可以从那里毫无问题地获取 showData
按钮的引用。所以你甚至可以把代码段放在那里。
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
// You can place the code segment here too
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
// ... Other code goes here.
}
您可以像这样修改 showData.setOnClickListener
showData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
// Call notifyDatasetChanged when the cursor is filled with data to load the list.
db_listView_adapter.notifyDatasetChanged();
}
});