Android SharedPreferences trong Fragment


90

Tôi đang cố đọc SharedPreferences bên trong Fragment. Mã của tôi là những gì tôi sử dụng để nhận tùy chọn trong bất kỳ Hoạt động nào khác.

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

Tôi gặp lỗi

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

Tôi đã cố gắng theo các liên kết này nhưng không may mắn khi truy cập SharedPreferences thông qua các phương thức tĩnhStatic SharedPreferences . Cảm ơn bạn cho bất kỳ giải pháp.

Câu trả lời:


254

Phương thức getSharedPreferenceslà một phương thức của Contextđối tượng, vì vậy chỉ gọi getSharedPreferences từ một Fragmentsẽ không hoạt động ... bởi vì nó không phải là một Context! (Activity là một phần mở rộng của Context, vì vậy chúng ta có thể gọi getSharedPreferences từ nó).

Vì vậy, bạn phải tải các ứng dụng của mình theo Ngữ cảnh

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

1
getSharedPreferences ("pref", 0); zero (0) có nghĩa là riêng tư / công cộng là gì?
Kailas

@Kailas đúng, chế độ, tức là WORLD_READABLE vv. developer.android.com/reference/android/content/… , int)
Jug6ernaut

5
0 tương tự với MODE_PRIVATE (hoặc Context.MODE_PRIVATE nếu được sử dụng trong một lớp không phải là phần mở rộng của Context, chẳng hạn như Fragment). Nó có nghĩa là chỉ ứng dụng được đề cập mới có thể truy cập các tùy chọn. Bạn không nên sử dụng WORLD_READABLE hoặc WORLD_WRITEABLE vì chúng không được dùng trong API 17+, chưa kể đến mối đe dọa bảo mật.
Ankit Aggarwal

1
thistừ khóa này có cần thiết khi làm this.getActivity().getShared..không?
Subby

2
@Subby không, chỉ gọi một cách rõ ràng là "cái này" là không cần thiết. Tôi đã làm điều đó vì sở thích cá nhân vì tôi ghét các cuộc gọi phương thức mơ hồ. Lần duy nhất "cái này" được yêu cầu là khi bạn đang cố gắng truy cập vào một đối tượng không tĩnh gốc khi bạn ở ngoài phạm vi của nó là trong một lớp / giao diện ẩn danh bên trong.
Jug6ernaut

14

Câu trả lời được đánh dấu không phù hợp với tôi, tôi phải sử dụng

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

BIÊN TẬP:

Hoặc chỉ cần thử xóa this:

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

8
Câu trả lời được đánh dấu không phù hợp với bạn vì bạn đang truy cập các tùy chọn chia sẻ mặc định. Một thiết kế tốt hơn là lưu trữ sở thích của bạn không phải như một vật dùng chung mà trong một không gian riêng và riêng tư, đó là những gì câu hỏi và câu trả lời ở đây.
zeeshan

8

Xin lưu ý rằng câu trả lời này được cung cấp bởi người dùng ở trên tôi là chính xác.

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

Tuy nhiên, nếu bạn cố gắng lấy bất kỳ thứ gì trong phân đoạn trước khi onAttach được gọi là getActivity () sẽ trả về null.


3

Bạn có thể tận dụng SharedPrefencestrong onAttachphương pháp của đoạn như thế này:

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


1

getActivity()và đã không onAttach()giúp tôi trong tình huống tương tự
có thể tôi đã làm sai điều gì đó
nhưng! Tôi đã tìm thấy một quyết định khác
Tôi đã tạo một trường Context thisContextbên trong Fragment của mình
Và có một ngữ cảnh hiện tại từ phương thức onCreateView
và bây giờ tôi có thể làm việc với pref được chia sẻ từ phân mảnh

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

1

Để xác định tùy chọn trong Fragment: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Để gọi một hoạt động khác hoặc phân mảnh dữ liệu tùy chọn: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...


0

Có thể lấy bối cảnh từ bên trong Fragment

Cứ làm đi

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;
    }
}

Bạn cũng có thể đính kèm một AndroidViewModeltrong onCreateViewphương thức triển khai một phương thức trả về ngữ cảnh ứng dụng

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

Có lẽ điều này sẽ hữu ích cho ai đó sau vài năm nữa. Cách mới, trên Androidx, để đi SharedPreferences()vào phân đoạn bên trong là triển khaigradle dependencies

implementation "androidx.preference:preference:1.1.1"

và sau đó, bên trong cuộc gọi phân mảnh

SharedPreferences preferences;
preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(getActivity());

0

sử dụng tính năng yêu cầu trong kotlin phân mảnh

 val sharedPreferences = requireActivity().getSharedPreferences(loginmasuk.LOGIN_DATA, Context.MODE_PRIVATE)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.