Reputation: 881
I'm changing locale programmatically from fragment and everything ok. There is one exception, the NavigationView menu, where language didn't changing. How to refresh it without recreate all activity.
Mainactivity code
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setEnabled(false);
DrawerLayout mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
R.layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" tools:openDrawer="start">
<include layout="@layout/app_bar_main" android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView android:id="@+id/nav_view"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_gravity="start" android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
fragment code after choose locale
LocaleHelper.setLocale(getActivity(), getResources().getStringArray(R.array.locale)[locale]);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();
<group android:checkableBehavior="single">
<item android:id="@+id/nav_contacts" android:icon="@drawable/ic_people_black_24dp"
android:title="@string/contacts" android:checked="true"/>
<item android:id="@+id/nav_invoices" android:icon="@drawable/ic_swap_horiz_black_24dp"
android:title="@string/invoices" />
<item android:id="@+id/nav_payments" android:icon="@drawable/ic_payment_black_24dp"
android:title="@string/payments" />
<item android:id="@+id/nav_history" android:icon="@drawable/ic_receipt_black_24dp"
android:title="@string/history" />
<item android:id="@+id/nav_settings" android:icon="@drawable/ic_settings_black_24dp"
android:title="@string/settings" />
<item android:id="@+id/nav_info"
android:title="@string/info" android:icon="@android:drawable/ic_dialog_info"/>
</group>
Thanx
Upvotes: 9
Views: 6965
Reputation: 556
latest solution in kotlin:
upgrade your appcompat version to 1.6.0
or later
implementation 'androidx.appcompat:appcompat:1.6.0'
create a function
fun setLocale(language: String?) {
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(language)
AppCompatDelegate.setApplicationLocales(appLocale)
}
then use it like
setLocale("en-EN")
it will update and refresh all language change/locale including NavigationView
Upvotes: 1
Reputation: 881
I've decided this problem
private void refreshNavigationView(){
getActivity().setContentView(R.layout.activity_main);
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
}
That's enought for refresh NavigationView after change locale
But I lose onNavigationItemSelected
As a result at Mainactivity
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the locale has changed
if (!currentLocale.equals(newConfig.locale)) {
currentLocale = newConfig.locale;
this.setContentView(R.layout.activity_main);
NavigationView navigationView = (NavigationView) this.findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(MainActivity.this);
}
}
At fragment
getActivity().onConfigurationChanged(getActivity().getResources().getConfiguration());
Upvotes: 2
Reputation: 1108
You can try below code. I haven't tested it but I hope it will work.
for (int i = 0, count = navigationView.getChildCount(); i < count; i++) {
final View child = navigationView.getChildAt(i);
if (child != null && child instanceof ListView) {
final ListView menuView = (ListView) child;
final HeaderViewListAdapter adapter = (HeaderViewListAdapter) menuView.getAdapter();
final BaseAdapter wrapped = (BaseAdapter) adapter.getWrappedAdapter();
wrapped.notifyDataSetChanged();
}
}
Upvotes: 0