Android SharedPreferences ใน Fragment


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 ผ่านวิธีการแบบคงที่และ SharedPreferences แบบคงที่ ขอบคุณสำหรับวิธีแก้ปัญหาใด ๆ

คำตอบ:


256

เมธอดgetSharedPreferencesคือเมธอดของContextอ็อบเจ็กต์ดังนั้นเพียงแค่เรียก getSharedPreferences จาก a Fragmentจะไม่ได้ผล ... เพราะมันไม่ใช่ Context! (กิจกรรมเป็นส่วนขยายของบริบทดังนั้นเราจึงสามารถเรียก getSharedPreferences ได้)

ดังนั้นคุณต้องรับบริบทแอปพลิเคชันของคุณโดย

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

1
getSharedPreferences ("pref", 0); ศูนย์ (0) หมายถึงอะไรส่วนตัว / สาธารณะ?
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
@ ซูบบี้ไม่เรียกว่า "นี่" อย่างชัดเจนไม่จำเป็น ฉันทำออกมาจากความชอบส่วนตัวเพราะฉันเกลียดการเรียกวิธีการที่คลุมเครือ ครั้งเดียวที่จำเป็นต้องใช้ "this" คือเมื่อคุณพยายามเข้าถึงพาเรนต์ออบเจ็กต์ที่ไม่ใช่สแตติกเมื่อคุณอยู่นอกขอบเขตที่อยู่ในคลาส / อินเทอร์เฟซภายในที่ไม่ระบุชื่อ
Jug6ernaut

14

คำตอบที่ทำเครื่องหมายไม่ได้ผลสำหรับฉันฉันต้องใช้

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 onAttachmethod of fragment ได้ดังนี้:

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


1

getActivity()และonAttach()ไม่ได้ช่วยฉันในสถานการณ์เดียวกัน
บางทีฉันอาจทำอะไรผิดพลาด
แต่! ฉันพบการตัดสินใจอีกครั้งที่
ฉันได้สร้างฟิลด์Context thisContextภายใน Fragment ของฉัน
และได้รับบริบทปัจจุบันจากวิธีการ onCreateView
และตอนนี้ฉันสามารถทำงานกับ pref ที่แชร์จากแฟรกเมนต์ได้

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

1

ในการกำหนดการตั้งค่าใน Fragment: 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;
    }
}

นอกจากนี้คุณยังอาจแนบAndroidViewModelใน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());

0

ใช้การกระทำที่จำเป็นในเศษชิ้นส่วน kotlin

 val sharedPreferences = requireActivity().getSharedPreferences(loginmasuk.LOGIN_DATA, Context.MODE_PRIVATE)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.