Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Перенос функциональности из Activity во Fragment

#java #android #android_fragment #activity #recyclerview


Проблема собственно следующая: я реализовал в своём приложении смену языков по нажатию
на кнопки в Activity (всё работает корректно), но я решил пойти дальше и попробовать
реализовать тоже самое только уже в RecyclerView и во Fragment.

И тут понеслись нюансы. Сам список с языками вывел во Fragment, добавил методы которые
у меня были в Activity, IDE вроде ошибок не выдаёт. 

Код моего Fragment'а:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_languages, container, false);
    initViews(view);
    initializeData();
    initializeAdapter();
    loadLocale();
    return view;
}

protected void initViews(View view) {
    recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
    layoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setHasFixedSize(true);
}

public void loadLocale() {
    String langPref = "Language";
    SharedPreferences prefs = this.getActivity().getSharedPreferences("CommonPrefs",
Activity.MODE_PRIVATE);
    String language = prefs.getString(langPref, "");
    changeLang(language);
}

public void changeLang(String lang) {
    if (lang.equalsIgnoreCase(""))
        return;
    myLocale = new Locale(lang);
    saveLocale(lang);
    Locale.setDefault(myLocale);
    android.content.res.Configuration config = new android.content.res.Configuration();
    config.locale = myLocale;
    getActivity().getBaseContext().getResources().updateConfiguration(config,
            getActivity().getBaseContext().getResources().getDisplayMetrics());
}

public void saveLocale(String lang) {
    String langPref = "Language";
    SharedPreferences prefs = this.getActivity().getSharedPreferences("CommonPrefs",
Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(langPref, lang);
    editor.commit();
}

private void initializeData() {
    languages = new ArrayList<>();
    languages.add(new Languages(getString(R.string.english)));
    languages.add(new Languages(getString(R.string.russian)));
    languages.add(new Languages(getString(R.string.deutsch)));
    languages.add(new Languages(getString(R.string.romana)));
}

private void initializeAdapter() {
    LanguagesAdapter languagesAdapter = new LanguagesAdapter(languages, position -> {
        String lang = "en";
        switch (position) {
            case 0:
                lang = "en";
                Toast.makeText(getActivity(), "En", Toast.LENGTH_SHORT).show();
                break;
            case 1:
                lang = "ru";
                Toast.makeText(getActivity(), "Ru", Toast.LENGTH_SHORT).show();

                break;
            case 2:
                lang = "de";
                Toast.makeText(getActivity(), "De", Toast.LENGTH_SHORT).show();

                break;
            case 3:
                lang = "ro";
                Toast.makeText(getActivity(), "Ro", Toast.LENGTH_SHORT).show();

                break;
            default:
                break;
        }
        changeLang(lang);
    });
    recyclerView.setAdapter(languagesAdapter);
}

@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (myLocale != null) {
        newConfig.locale = myLocale;
        Locale.setDefault(myLocale);
        getActivity().getBaseContext().getResources().updateConfiguration(newConfig,
                getActivity().getBaseContext().getResources().getDisplayMetrics());
    }
}


}

В коде адаптера реализовал метод, который будет изменять язык, но по умолчанию поставил
переменную "ru" и теперь при нажатии на русский, язык меняется только на русский, как
сделать выборку? Чтоб было более одного языка?

Метод в коде адаптера:

@Override
public void onBindViewHolder(LanguageViewHolder personViewHolder, final int position) {
    personViewHolder.languageName.setText(languages.get(position).name);

    personViewHolder.languageName.setOnClickListener(v -> {
        Resources res = context.getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        android.content.res.Configuration conf = res.getConfiguration();
        String language_code = "ru";
        conf.setLocale(new Locale(language_code.toLowerCase()));
        res.updateConfiguration(conf, dm);
    });
}


P.S. Возможно есть какой то другой способ реализовать данную фичу, я только за.
    


Ответы

Ответ 1



Возможно не хватает других частей кода, но мне кажется, что у Вас будет переключаться язык только на русский, потому что при нажатии он захардкожен: String language_code = "ru"; //надо languages.get(position).name? conf.setLocale(new Locale(language_code.toLowerCase())); res.updateConfiguration(conf, dm); В любом случае, Вам самому было бы удобнее получать код языка из адаптера в Ваш контроллер. Ясно, что проблема не в этом, ведь через адаптер желаемого результата тоже можно добиться, но как минимум такая структура упростит отладку и отслеживание кода. В классе адаптера создайте интерфейс. public interface LanguageSwitcher{ void onLanguageSelected(String local); } Используйте его как аргумент конструктора адаптера: private LanguageSwitcher switcher; public LanguageAdapter(LanguageSwitcher switcher){ this.switcher = switcher //другие аргументы } Обработка нажатия: personViewHolder.languageName.setOnClickListener(v -> { switcher.onLanguageSelected(languages.get(position).name); }); В классе фрагмента просто имплементируйте LanguageAdapter.LanguageSwitcher и опишите логику смены языка в расширяемом методе, а затем при создании экземпляра адаптера не забудте передать аргумент интерфейса new LanguageAdapter(this)

Комментариев нет:

Отправить комментарий