【问题标题】:Fragment ListView adapter notifyDataSetChanged() from MainActivity来自 MainActivity 的片段 ListView 适配器 notifyDataSetChanged()
【发布时间】:2023-03-10 20:06:01
【问题描述】:

首先,如果我的思想不正确,请纠正我,这是我第一次使用 Fragment 并且不擅长 ListView 适配器。

我目前正在使用DrawerLayout,它由您所期望的片段组成,我有一个FAB,单击它会在SQLite db 条目中添加一个新条目,并刷新ListView(从数据库中提取的数据)。

我的想法是我可以在 ActivityMain 中获取 ListView 适配器(在 Profiles 片段类中)(因为 FAB 不是片段的一部分,并且根据当前片段将有不同的操作),然后调用 .notifyDataSetChanged( )

Profiles 片段类

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 类中

// 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 点击时尝试做的事情,幻数只是一个 int,它从 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();

片段类内部

public void updateListView(){
    adapter.notifyDataSetChanged();
}

我还尝试从 Profiles 片段类中返回适配器,我认为这是解决此问题的错误方法。

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

在我看来,似乎无法从片段 Profiles 类外部访问适配器,不确定是否是这样 - 即使不确定如何解决这个问题。让我知道是否需要任何其他代码/logcat。谢谢!

【问题讨论】:

  • 如果你想让一个FAB动作依赖于fragment,那为什么不能在每个fragment布局中添加一个FAB呢?
  • @CodeCody 老实说,我没有想到这一点,因为 FAB 已自动添加到 ActivityMain 并且在所有片段上都可见。我使用 switch 语句来区分正在使用的片段并相应地设置 onClick 操作。如果将 FAB 添加到每个片段是更好的方法,我会试一试!

标签: android listview android-fragments android-arrayadapter


【解决方案1】:

对于遇到此问题的任何人,我在这里找到的解决方案是:notifyDataSetChange not working from custom adapter(最佳答案效果很好)。

虽然我确实实现了 CodeCody 将 FAB 放在单个片段中的想法,但我可以安全地恢复到之前的状态,但不确定哪个选项更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多