我在保存片段活动中以编程方式创建的视图时遇到了麻烦

时间:2019-03-10 02:46:39

标签: android android-fragments sharedpreferences android-view

我进行了设置,以便通过共享首选项保存用户创建的视图。该信息可以很好地保存,但是当我尝试使用共享的首选项信息重新创建这些视图时,应用程序崩溃。问题似乎是当调用我的重新创建视图的函数时,片段未完全加载。但是,我不确定应该在哪里调用加载首选项以确保所有视图都已膨胀。我试过了onResume(),onStart()和其他一些可能性,并且都导致了相同的问题。

我的片段设置如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dice);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Create the adapter that will return a fragment for each of the two primary sections of the activity.

    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.

    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);

    mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));


}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_dice, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    public PlaceholderFragment() {
    }

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_dice, container, false);
        return rootView;
    }
}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {
    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        switch (position) {
            case 0:
                fragment = new fragment_dice();
                break;
            case 1:
                fragment = new fragment_history();
                break;
        }
        return fragment;
    }

    @Override
    public int getCount() {
        // Show 2 total pages.
        return 2;

    }
}

骰子片段Java文件:

public class fragment_dice extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable 
ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_dice, container, false);
    return v;
}

}

历史Java文件:

public class fragment_history extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_history, container, false);
    return v;
}

}

共享首选项功能:

public void onPause() {
    super.onPause();
    SharedPreferences sp = getSharedPreferences("preferences", Context.MODE_PRIVATE);
    SharedPreferences.Editor spEditor = sp.edit();
    Log.d("test", "Save Size " + createdDiceNames.size());
    spEditor.putInt("Die_size", createdDiceNames.size());
    for (int i = 0; i < createdDiceNames.size(); i++) {
        spEditor.remove("Die_" + i);
        spEditor.putString("Die_" + i, createdDiceNames.get(i));
    }
    spEditor.commit();
}
public void loadPreferences() {
    SharedPreferences mSp = getSharedPreferences("preferences", Context.MODE_PRIVATE);
    SharedPreferences.Editor spEditor = mSp.edit();
    createdDiceNames.clear();
    int size = mSp.getInt("Die_size", 0);
    Log.d("test", "Load Size " + size);
    for (int i = 0; i < size; i++) {
        customDiceName = mSp.getString("Die_" + i, "").replaceAll(".+_","");
        for (int b = 0; b < createdDiceNames.size(); b++) {
            Log.d("test", "Array Value " + createdDiceNames.get(b));
        }
        Log.d("test", "Dice Name " + customDiceName);
        //This function is where the views are re-inflated and this is where the error occurs because the table layout has not yet loaded in the fragment
        createCustomDice();
    }
}

我已经尝试在应用程序启动后使用按钮调用负载首选项功能,以确保其正常工作并且确实能够正常工作。我的问题是将函数放在哪里,以便仅在加载片段视图后才加载该函数,而不会导致其崩溃。

1 个答案:

答案 0 :(得分:0)

如果您坚持使用“共享首选项”,我们需要查看您的日志。

无论如何,我认为您可能想使用数据库。我建议您使用任何无模式的(例如ObjectBox),但是您应该使用任何类型。共享首选项用于键值对象(如首选项),但不能用于动态更改对象。