Android SharedPreferences у фрагменті


90

Я намагаюся прочитати SharedPreferences усередині Fragment. Мій код - це те, що я використовую для отримання переваг у будь-якій іншій діяльності.

     SharedPreferences preferences = getSharedPreferences("pref", 0);

Я отримую помилку

    Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper    

Я намагався перейти за цими посиланнями, але не маючи щастя отримати доступ до SharedPreferences за допомогою статичних методів та Static SharedPreferences . Дякуємо за будь-яке рішення.

Відповіді:


253

Метод getSharedPreferencesє методом Contextоб'єкта, тому просто виклик getSharedPreferences з a Fragmentне буде працювати ... тому що це не контекст! (Activity є розширенням контексту, тому ми можемо викликати getSharedPreferences з нього).

Тож ви повинні отримати свої програми Context до

// this = your fragment
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

1
getSharedPreferences ("pref", 0); нуль (0) означає, що приватне / державне?
Kailas

@Kailas правильний, режим, тобто WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut

5
0 є аналогом MODE_PRIVATE (або Context.MODE_PRIVATE, якщо використовується в класі, який не є розширенням контексту, наприклад, Fragment). Це означає, що лише програма, про яку йде мова, може отримати доступ до налаштувань. Не слід використовувати WORLD_READABLE або WORLD_WRITEABLE, оскільки вони застаріли в API 17+, не кажучи вже про загрозу безпеці.
Ankit Aggarwal

1
чи потрібно це thisключове слово при виконанні this.getActivity().getShared..?
Subby

2
@Subby ні, явно називати просто "це" ніколи не потрібно. Я зробив це з особистих переваг, оскільки ненавиджу неоднозначні виклики методів. Єдиний раз, коли потрібно "це", це коли ви намагаєтесь отримати доступ до батьківського нестатичного об'єкта, коли ви перебуваєте поза його сферою дії, перебуваючи в анонімному внутрішньому класі / інтерфейсі.
Jug6ernaut

13

Позначена відповідь для мене не спрацювала, мені довелося скористатися

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());

РЕДАГУВАТИ:

Або просто спробуйте видалити this:

SharedPreferences prefs = getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

8
Позначена відповідь не працювала для вас, оскільки ви отримуєте доступ до спільних налаштувань за замовчуванням. Кращий дизайн - зберігати свої уподобання не як спільний об’єкт, а в окремому приватному просторі, саме про це тут питання і відповідь.
zeeshan

8

У якості застереження ця відповідь, надана користувачем, наді мною, є правильною.

SharedPreferences preferences = this.getActivity().getSharedPreferences("pref",0);

Однак, якщо ви спробуєте отримати щось у фрагменті до того, як onAttach буде викликано, getActivity () поверне null.


3

Ви можете зробити метод SharedPrefencesin onAttachфрагментом таким:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    SharedPreferences preferences = context.getSharedPreferences("pref", 0);
}


1

getActivity()і не onAttach()допоміг мені в тій же ситуації,
можливо, я зробив щось не так,
але! Я знайшов інше рішення,
я створив поле Context thisContextвсередині мого фрагмента,
і отримав поточний контекст від методу onCreateView,
і тепер я можу працювати із спільним преф з фрагмента

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {   
...   
thisContext = container.getContext();   
...   
}

1

Щоб визначити перевагу у фрагменті: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Щоб викликати іншу діяльність або фрагментувати дані налаштувань: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...


0

Можна отримати контекст зсередини Fragment

Просто зробіть

public class YourFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        final View root = inflater.inflate(R.layout.yout_fragment_layout, container, false);
        // get context here
        Context context = getContext();
        // do as you please with the context


        // if you decide to go with second option
        SomeViewModel someViewModel = ViewModelProviders.of(this).get(SomeViewModel.class);
        Context context = homeViewModel.getContext();
        // do as you please with the context
        return root;
    }
}

Ви також можете долучити метод AndroidViewModelin, onCreateViewякий реалізує метод, який повертає контекст програми

public class SomeViewModel extends AndroidViewModel {

    private MutableLiveData<ArrayList<String>> someMutableData;
    Context context;

    public SomeViewModel(Application application) {
        super(application);
        context = getApplication().getApplicationContext();
        someMutableData = new MutableLiveData<>();
        .
        .
     }

     public Context getContext() {
         return context
     }
  }

0

Можливо, це комусь корисно через кілька років. Новим способом, на Androidx, потрапити SharedPreferences()всередину фрагмента є впровадження вgradle dependencies

implementation "androidx.preference:preference:1.1.1"

а потім усередині виклику фрагмента

SharedPreferences preferences;
preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(getActivity());
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.