koa73
koa73

Reputation: 881

Refresh NavigationView menu after change locale

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

Answers (3)

Shakil Ahmed Shaj
Shakil Ahmed Shaj

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

koa73
koa73

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

theJango
theJango

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

Related Questions