来自 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 放入单个片段的想法,但我可以安全地恢复到之前的状态,但不确定哪个选项更好。