Android / Java | TextView .setText панели навигации не работает через SharedPreferences

У меня есть фрагмент, который позволяет пользователю изменять свое имя пользователя, которое будет отображаться в TextView внутри ящика навигации. Фрагмент, SettingsFragment, раздувается в MainActivity.

SettingsFragment имеет EditText, где пользователь вводит свое имя пользователя и кнопку для применения изменений. Панель навигации была создана в MainActivity, поэтому я настроил SharedPreferences для отправки имени пользователя в MainActivity. Затем я приступил к изменению TextView в навигационном ящике с помощью .setText(username), однако ничего не происходит. Но когда я перезапускаю приложение, TextView в навигационном ящике меняется на фактическое имя пользователя, которое пользователь ввел в EditText.

SettingsFragment.java:

public class SettingsFragment extends Fragment {


public SettingsFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_settings, container, false);

    final TextInputEditText teiUserName = view.findViewById(R.id.teiUserName);
    final TextView tvEditTextSub = view.findViewById(R.id.tvEditTextSubstitute);
    Button btnApplyChanges = view.findViewById(R.id.btnApplyChanges);

    btnApplyChanges.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            final String user_name = String.valueOf(teiUserName.getText());

            tvEditTextSub.setText(user_name);

            SharedPreferences.Editor editor = getActivity().getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
            editor.putString("name", user_name);
            editor.apply();

        }
    });

    return view;
}}

Настройки Фрагмента XML:

<FrameLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:padding = "10dp"
tools:context = "com.miguelpeachey.marketplacesimulator.Fragments.SettingsFragment">

<RelativeLayout
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">

    <android.support.design.widget.TextInputEditText
        android:id = "@+id/teiUserName"
        android:layout_width = "248dp"
        android:layout_height = "wrap_content"
        android:layout_above = "@+id/btnApplyChanges"
        android:layout_marginBottom = "28dp"
        android:text = "User"
        android:textColorHint = "#000" />

    <Button
        android:id = "@+id/btnApplyChanges"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_alignParentBottom = "true"
        android:layout_centerHorizontal = "true"
        android:layout_marginBottom = "28dp"
        android:background = "#33993f"
        android:padding = "12dp"
        android:text = "Apply Changes"
        android:textColor = "#FFF" />

</RelativeLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

Fragment fragment;

SharedPreferences sharedPreferences;

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

    Toolbar toolbar = findViewById(R.id.toolbar);
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    View headerView = navigationView.getHeaderView(0);
    final TextView tvDrawerUsername = headerView.findViewById(R.id.tvDrawerUsername);
    setSupportActionBar(toolbar);

    sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);

    final String usernameID = sharedPreferences.getString("name", "User");

    if (drawer.isDrawerOpen(GravityCompat.START)) {
        tvDrawerUsername.setText(usernameID);
    }}

В MainActivity.java больше кода, но нет необходимости включать его.


В MainActivity.java я также пробовал:

if (drawer.isDrawerOpen(GravityCompat.START)) {
        tvDrawerUsername.setText(usernameID);
    }

Но он даже не изменил TextView в навигационном ящике (tvDrawerUsername) после перезапуска приложения.


В заключение, приложение не будет обновлять tvDrawerUsername сразу после нажатия кнопки, а только после того, как я перезапущу приложение.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
91
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте определить атрибут TextView в определении класса SettingsFragment:

public class SettingsFragment extends Fragment {

TextView tv;

public SettingsFragment() {
    // Required empty public constructor
}

Определите установщик для этого атрибута в том же классе:

public void setTextView(TextView tv){
    this.tv = tv
}

И из вашей активности, после инициализации ваших fragment и textView, передайте textView через только что созданный установщик:

fragment = new SettingsFragment();
fragment.setTextView(tvDrawerUsername);

Наконец, добавьте textView.setText(user_name); в метод onlick():

 btnApplyChanges.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final String user_name = String.valueOf(teiUserName.getText());

                tvEditTextSub.setText(user_name);

                SharedPreferences.Editor editor = getActivity().getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
                editor.putString("name", user_name);
                editor.apply();
                textView.setText(user_name);

            }
        });

Надеюсь это поможет

Является ли textView TextView элементом навигации? Когда я запускаю приложение с textView.setText (user_name); он дает мне исключение NullPointerException: попытка вызвать виртуальный метод void android.widget.TextView.setText (java.lang.CharSequence) для ссылки на нулевой объект в com.miguelpeachey.marketplacesimulator.Fragments.SettingsFra‌ gment $ 1.onClick (Sett‌ IngsFragment.java:53‌)

Miguel P. 21.12.2018 13:15

Да, но следует использовать фрагмент. SetTextView (tvDrawerUsername) после TextView tvDrawerUsername = headerView.findViewById (R.id.tvDrawerUsername);

B.M 21.12.2018 13:20
Ответ принят как подходящий

Попробуй это:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

Fragment fragment;

SharedPreferences sharedPreferences;

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

    sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);Toolbar toolbar = findViewById(R.id.toolbar);
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    View headerView = navigationView.getHeaderView(0);
    final TextView tvDrawerUsername = headerView.findViewById(R.id.tvDrawerUsername);

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, null, "navigation_drawer_open", "navigation_drawer_close") {
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                // Do whatever you want here
            }

            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);

                final String usernameID = sharedPreferences.getString("name", "User");
                tvDrawerUsername.setText(usernameID);
            }
        };
    drawer.addDrawerListener(toggle);
    toggle.syncState();
    setSupportActionBar(toolbar);
}

Добавлено 'sharedPreferences = getSharedPreferences ("myPrefs", Context.MODE_PRIVATE);' в onDrawerOpened и он работает.

Miguel P. 21.12.2018 13:39

Другие вопросы по теме