来自 MainActivity 的 Fragment ListView 适配器 notifyDataSetChanged()
Fragment ListView adapter notifyDataSetChanged() from MainActivity
首先,如果我的意识形态不正确,请纠正我,这是我第一次使用片段而不擅长 ListView 适配器。
我目前正在使用 DrawerLayout
,它由您所期望的片段组成,我有一个 FAB,单击它会向 SQLite 数据库条目添加一个新条目,并将刷新 ListView(从中提取的数据分贝)。
我的想法是,我可以在 ActivityMain 中获取 ListView 适配器(在 Profiles 片段 class 中)(因为 FAB 不是片段的一部分,并且会根据当前片段执行不同的操作)然后调用 .notifyDataSetChanged()
个人档案片段class
public class Profiles extends Fragment{
public ProfileListAdapter adapter;
(...)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DBHandler db = new DBHandler(getActivity().getBaseContext());
adapter = new ProfileListAdapter(getActivity().getBaseContext(), db.getAllProfiles());
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
ListView profileListView = (ListView)view.findViewById(R.id.profileListView);
profileListView.setAdapter(adapter);
}
ProfilesListAdapter(来自 here)
public class ProfileListAdapter extends ArrayAdapter<Profile> {
private static class ViewHolder {
TextView name;
}
public ProfileListAdapter(Context context, ArrayList<Profile> profileList) {
super(context, R.layout.profile_row, profileList);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Profile profile = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.profile_row, parent, false);
viewHolder.name = (TextView) convertView.findViewById(R.id.profileListRowValue);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.name.setText(profile.name);
// Return the completed view to render on screen
return convertView;
}
}
DBHelper 内部 class
// Getting All Profiles
public ArrayList<Profile> getAllProfiles() {
ArrayList<Profile> profileListItems = new ArrayList<Profile>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_PROFILE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, new String[] {});
// looping through all rows and adding to list
if (cursor.moveToLast()) {
do {
Profile profile = new Profile();
profile.setId(Integer.parseInt(cursor.getString(0)));
profile.setName(cursor.getString(1));
// Adding contact to list
profileListItems.add(profile);
} while (cursor.moveToPrevious());
}
// return contact list
cursor.close();
return profileListItems;
}
这就是我在 MainActivity 中控制的 FAB 单击时尝试做的事情,幻数只是一个从 0 开始并递增 1 的整数,以便我更轻松地测试 db / ListView。
db.addProfile(new Profile("Test Profile " + magicNumber));
magicNumber++;
FragmentManager fm = getSupportFragmentManager();
Profiles fragment = (Profiles) fm.findFragmentById(R.id.fragmentProfiles);
//I gave the fragment xml main FrameLayout an ID
fragment.updateListView();
碎片内部class
public void updateListView(){
adapter.notifyDataSetChanged();
}
我还尝试从 Profiles 片段 class 返回适配器,我认为这是解决此问题的错误方法。
public ProfileListAdapter getAdapter(){
return adapter;
}
我总是以
结束
java.lang.NullPointerException: Attempt to invoke virtual method 'void layout.Profiles.updateListView()' on a null object reference
或
java.lang.NullPointerException: Attempt to invoke virtual method 'com.xxxxx.xxxxx.appName.ProfileListAdapter layout.Profiles.getAdapter()' on a null object reference
在我的菜鸟看来,似乎无法从片段配置文件 class 外部访问适配器,不确定是否是这样 - 即使不确定如何解决这个问题。让我知道是否需要任何其他代码/logcat。谢谢!
对于遇到这个问题的任何人,我找到的解决方案是:notifyDataSetChange not working from custom adapter(最佳答案很有效)。
尽管我确实实现了 CodeCody 将 FAB 放入单个片段的想法,但我可以安全地恢复到之前的状态,但不确定哪个选项更好。
首先,如果我的意识形态不正确,请纠正我,这是我第一次使用片段而不擅长 ListView 适配器。
我目前正在使用 DrawerLayout
,它由您所期望的片段组成,我有一个 FAB,单击它会向 SQLite 数据库条目添加一个新条目,并将刷新 ListView(从中提取的数据分贝)。
我的想法是,我可以在 ActivityMain 中获取 ListView 适配器(在 Profiles 片段 class 中)(因为 FAB 不是片段的一部分,并且会根据当前片段执行不同的操作)然后调用 .notifyDataSetChanged()
个人档案片段class
public class Profiles extends Fragment{
public ProfileListAdapter adapter;
(...)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DBHandler db = new DBHandler(getActivity().getBaseContext());
adapter = new ProfileListAdapter(getActivity().getBaseContext(), db.getAllProfiles());
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
ListView profileListView = (ListView)view.findViewById(R.id.profileListView);
profileListView.setAdapter(adapter);
}
ProfilesListAdapter(来自 here)
public class ProfileListAdapter extends ArrayAdapter<Profile> {
private static class ViewHolder {
TextView name;
}
public ProfileListAdapter(Context context, ArrayList<Profile> profileList) {
super(context, R.layout.profile_row, profileList);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Profile profile = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.profile_row, parent, false);
viewHolder.name = (TextView) convertView.findViewById(R.id.profileListRowValue);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.name.setText(profile.name);
// Return the completed view to render on screen
return convertView;
}
}
DBHelper 内部 class
// Getting All Profiles
public ArrayList<Profile> getAllProfiles() {
ArrayList<Profile> profileListItems = new ArrayList<Profile>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_PROFILE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, new String[] {});
// looping through all rows and adding to list
if (cursor.moveToLast()) {
do {
Profile profile = new Profile();
profile.setId(Integer.parseInt(cursor.getString(0)));
profile.setName(cursor.getString(1));
// Adding contact to list
profileListItems.add(profile);
} while (cursor.moveToPrevious());
}
// return contact list
cursor.close();
return profileListItems;
}
这就是我在 MainActivity 中控制的 FAB 单击时尝试做的事情,幻数只是一个从 0 开始并递增 1 的整数,以便我更轻松地测试 db / ListView。
db.addProfile(new Profile("Test Profile " + magicNumber));
magicNumber++;
FragmentManager fm = getSupportFragmentManager();
Profiles fragment = (Profiles) fm.findFragmentById(R.id.fragmentProfiles);
//I gave the fragment xml main FrameLayout an ID
fragment.updateListView();
碎片内部class
public void updateListView(){
adapter.notifyDataSetChanged();
}
我还尝试从 Profiles 片段 class 返回适配器,我认为这是解决此问题的错误方法。
public ProfileListAdapter getAdapter(){
return adapter;
}
我总是以
结束java.lang.NullPointerException: Attempt to invoke virtual method 'void layout.Profiles.updateListView()' on a null object reference
或
java.lang.NullPointerException: Attempt to invoke virtual method 'com.xxxxx.xxxxx.appName.ProfileListAdapter layout.Profiles.getAdapter()' on a null object reference
在我的菜鸟看来,似乎无法从片段配置文件 class 外部访问适配器,不确定是否是这样 - 即使不确定如何解决这个问题。让我知道是否需要任何其他代码/logcat。谢谢!
对于遇到这个问题的任何人,我找到的解决方案是:notifyDataSetChange not working from custom adapter(最佳答案很有效)。
尽管我确实实现了 CodeCody 将 FAB 放入单个片段的想法,但我可以安全地恢复到之前的状态,但不确定哪个选项更好。