片段ListView适配器来自MainActivity的notifyDataSetChanged()

时间:2016-07-28 22:27:54

标签: android listview android-fragments android-arrayadapter

首先请纠正我,如果我的意识形态不正确,这是我第一次使用片段而不是ListView适配器。

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

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

“个人档案”片段类

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点击控制所要做的事情,幻数只是一个从0开始的int,并且增加了一个让我更容易测试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();

Fragment类中的内容

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

对于我的noobish眼睛,似乎无法从片段Profiles类外部访问适配器,不确定它是什么 - 即使如此不确定如何解决这个问题。如果需要任何其他代码/ logcat,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:0)

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

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