我在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);
答案 0 :(得分:0)
您需要从findViewById
dbView
移除onClickListener
的{{1}}并将其放入showData
。
请删除以下内容。
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
中找不到ListView
个ID。设置View
的内容视图后,您可以将Activity
放在任何位置,它会完美地找到关联的布局参考。
如果是findViewById
,正如您所见,Fragment
函数会返回onCreateView
个对象作为View
被夸大的引用。因此,您需要在View
中找到ListView
。这就是为什么您需要View
来搜索view.findViewById
中ListView
的{{1}}的引用ID。
当您将View
放入listView = (ListView) view.findViewById(R.id.dbView);
时,它会获得按钮showData.setOnClickListener
的引用,并尝试在showData
中找到dbView
导致错误的视图。
因此有必要在Button
中获取列表的引用并在那里设置适配器。然后,当onCreateView
填充数据时,您可以轻松调用notifyDatasetChanged()
重新加载列表。
顺便说一句,您可以将代码段放在cursor
函数中,因为您可以从那里获得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