【问题标题】:Why does using Locale in Fragment result in lots of bugs?为什么在 Fragment 中使用 Locale 会导致很多错误?
【发布时间】:2026-01-23 21:00:01
【问题描述】:

我有两个activity,分别是MainActivity.java和Settings.java,其他都是fragment,MainActivity是fragment_container,每个fragment都附在这里。设置活动具有更改语言的设置。 MainActivity 包含三个按钮,如果我单击按钮,同一容器中的下一个片段将显示列表视图。

如果我更改语言,那么如果我从设置活动返回 MainActivity,然后单击按钮,列表视图仍显示英语。如果我按下并再次单击按钮,那么最终语言会改变。虽然菜单(onOptionsCreateMenu)中的语言没有改变。我将这些设置保存在 sharedPreferences 中。

现在,在我退出我的应用程序并再次返回之后,如果我第一次单击按钮,语言是英语,如果我返回片段并再次单击按钮,它会更改语言。我可能会错过什么?我在 Stack Overflow 中搜索了相关问题,但这些都没有帮助。以下是我的代码:

MainActivity.java(包含所有片段)

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ImageButton img_boy, img_girl, img_dog;

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

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);

    img_boy = (ImageButton) findViewById(R.id.img_boy);
    img_boy.setOnClickListener(this);
    img_girl = (ImageButton) findViewById(R.id.img_girl);
    img_girl.setOnClickListener(this);
    img_dog = (ImageButton) findViewById(R.id.img_dog);
    img_dog.setOnClickListener(this);


    Boolean isFirstRun = getSharedPreferences("Preference", MODE_PRIVATE).getBoolean("isFirstRun", true);
    if (isFirstRun) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Dark_theme);
        builder.setTitle(R.string.chooselanguage).setItems(R.array.language, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                switch (i) {
                    case 1:
                        SharedPreferences ensharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                        SharedPreferences.Editor eneditor = ensharedPreferences.edit();
                        eneditor.putString("language", "en");
                        eneditor.commit();
                    case 2:
                        SharedPreferences npsharedPrefrences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                        SharedPreferences.Editor npeditor = npsharedPrefrences.edit();
                        npeditor.putString("language", "ne");
                        npeditor.commit();
                        break;
                }
            }
        }).setCancelable(false).create().show();
        getSharedPreferences("Preference", MODE_PRIVATE).edit().putBoolean("isFirstRun", false).commit();
    }
}
public void onBackPressed() {
    CallForBackButton();
}
private void CallForBackButton() {
    int count = getFragmentManager().getBackStackEntryCount();

    switch (count) {
        case 0:
            QuitDialog();
            break;
        default:
            getFragmentManager().popBackStack();
            break;
    }
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.settings:
            startActivity(new Intent(MainActivity.this, Settings.class));
            break;
        case android.R.id.home:
            CallForBackButton();
            break;
        case R.id.exit:
            QuitDialog();

    }
    return true;
}

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.img_boy:
            Recycler rc = new Recycler();
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.fragment_container, rc);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
            break;

        // other case 
}
}

Settings.java

public class Settings extends AppCompatActivity {
public static final String DEFAULT = "N/A";
Switch aSwitch, aSwitch2;


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



    aSwitch = (Switch) findViewById(R.id.swic);
    aSwitch2 = (Switch) findViewById(R.id.swic2);

    SharedPreferences sharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
    String s1 = sharedPreferences.getString("language", DEFAULT);

    if (s1.matches("ne")) {
        aSwitch.setChecked(true);
    } else {
        aSwitch.setChecked(false);
    }

    aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

            if (aSwitch.isChecked()) {
                SharedPreferences npsharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                SharedPreferences.Editor npeditor = npsharedPreferences.edit();
                npeditor.putString("language","ne");
                npeditor.commit();
                aSwitch.setChecked(true);
                Toast.makeText(Settings.this, "Nepali Language Selected", Toast.LENGTH_LONG).show();


            } else {
                SharedPreferences ensharedPreferences = getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
                SharedPreferences.Editor eneditor = ensharedPreferences.edit();
                eneditor.putString("language","en");
                eneditor.commit();
                Toast.makeText(Settings.this, "English Language Selected", Toast.LENGTH_LONG).show();
                aSwitch.setChecked(false);
            }
        }
    });

}
}

Recycler.java(这是 RecyclerView,我在其中显示文本)

public class Recycler extends Fragment {
private List<Name> names;
RecyclerView rv;
String[] nameCollection;
public static final String DEFAULT = "N/A";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.recyclerview, container, false);
    rv = (RecyclerView) view.findViewById(R.id.rv);
    nameCollection = getActivity().getResources().getStringArray(R.array.babies_names);
    LinearLayoutManager llm = new LinearLayoutManager(getActivity());
    rv.setLayoutManager(llm);
    rv.setHasFixedSize(true);
    initializeData();
    initializeAdapter();
    return view;
}

private void initializeAdapter() {
    rvadapter adapter = new rvadapter(names);
    rv.setAdapter(adapter);
}

public void initializeData() {
    names = new ArrayList<>();

    SharedPreferences sharedPreferences = getActivity().getSharedPreferences("selectedLanguage", Context.MODE_PRIVATE);
    String pine= sharedPreferences.getString("language", DEFAULT);
    String languageToLoad=pine;
    Locale locale=new Locale(languageToLoad);//Set Selected Locale
    Locale.setDefault(locale);//set new locale as default
    Configuration config = new Configuration();//get Configuration
    config.locale = locale;//set config locale as selected locale
    getActivity().getResources().updateConfiguration(config, getActivity().getResources().getDisplayMetrics());
    for (int i = 0; i < nameCollection.length; i++) {
            names.add(new Name(nameCollection[i]));
        }
}
}

我只需要修复用户选择的语言。

还有一件事,如果我退出应用程序但没有关闭最近的应用程序,那么如果我再次返回我的应用程序,那么一切正常,菜单上的语言也会改变(onOptionMenu)。我认为快速解决此问题的方法是将其保存在 savedInstanceState 中,但我不确定,也不知道如何在我的情况下使用它。

【问题讨论】:

    标签: android android-fragments android-sharedpreferences


    【解决方案1】:

    我在 onStart() 回调中调用 MainActivity.java 下的 Locale,而不是在 recyclerView 上调用 instalizeData(),现在一切正常:D

    【讨论】: