So my app has a bottom navigation where one of the page is the settings page. In the settings fragment, I inherited from PreferenceFragment. Here is the code for the SettingsFragment class:
class SettingsFragment : PreferenceFragmentCompat() {
private lateinit var binding: FragmentSettingsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSettingsBinding.inflate(inflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onCreatePreferences(bundle: Bundle?, s: String?) {
addPreferencesFromResource(R.xml.preferences)
}
}
Here is the main activity where the transaction happens:
class MainActivity : AppCompatActivity(){
private lateinit var binding: ActivityMainBinding
//Make it a global variable
private val homeFragment = HomeFragment()
private val profileFragment = ProfileFragment()
private val favoriteFragment = FavoriteFragment()
private val settingsFragment = SettingsFragment()
companion object {
private val TAG = MainActivity::class.java.simpleName
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
replaceFragment(homeFragment)
binding.bottomNavigation.setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.ic_home -> replaceFragment(homeFragment)
R.id.ic_profile -> replaceFragment(profileFragment)
R.id.ic_favorite -> replaceFragment(favoriteFragment)
R.id.ic_settings -> replaceFragment(settingsFragment)
}
true
}
}
private fun replaceFragment(fragment: Fragment){
if (fragment!=null){
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container,fragment)
transaction.commit()
}
}
}
Here is also the log:
2021-04-15 11:42:42.566 20177-20177/com.dicoding.githubclone E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dicoding.githubclone, PID: 20177
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)' on a null object reference
at androidx.preference.PreferenceFragmentCompat.bindPreferences(PreferenceFragmentCompat.java:483)
at androidx.preference.PreferenceFragmentCompat.onViewCreated(PreferenceFragmentCompat.java:272)
at com.dicoding.githubclone.fragment.SettingsFragment.onViewCreated(SettingsFragment.kt:36)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:239)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
I'm not sure how to fix this. Can anyone help me?
As PreferenceFragmentCompat
creates it's own recycler view , so don't use onCreateView
. Like:
class SettingsFragment : PreferenceFragmentCompat() {
// private lateinit var binding: FragmentSettingsBinding
/* override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSettingsBinding.inflate(inflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}*/
override fun onCreatePreferences(bundle: Bundle?, s: String?) {
addPreferencesFromResource(R.xml.preferences)
}
}