I have an error saying "Error inflating class fragment". I saw different solutions like one is saying to extend fragment activity but this is not fragment this is an activity so are there any other solutions?
Following is my main activity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
addFragment(HomeFragment.newInstance())
binding.navView.show(0)
binding.navView.add(MeowBottomNavigation.Model(1, R.drawable.ic_dashboard_black_24dp))
binding.navView.add(MeowBottomNavigation.Model(2, R.drawable.ic_dashboard_black_24dp))
binding.navView.setOnClickMenuListener {
when(it.id){
0->{
Toast.makeText(this, "Home Fragment", Toast.LENGTH_SHORT).show()
replaceFragment(HomeFragment.newInstance())
}
1->{
Toast.makeText(this, "Notifications Fragment", Toast.LENGTH_SHORT).show()
replaceFragment(NotificationFragment.newInstance())
}
}
}
}
private fun replaceFragment(fragment: Fragment) {
val fragmentTransition = supportFragmentManager.beginTransaction()
fragmentTransition.replace(R.id.nav_host_fragment_activity_main, fragment).addToBackStack(Fragment::class.java.simpleName).commit()
}
private fun addFragment(fragment: Fragment) {
val fragmentTransition = supportFragmentManager.beginTransaction()
fragmentTransition.add(R.id.nav_host_fragment_activity_main, fragment).addToBackStack(Fragment::class.java.simpleName).commit()
}
}
I changes frgment to frameLayout and error is gone now
Related
I created a Login/Register Page and I get this error while trying to click Register Button.This method should send me to Register Page where I can register a new account.The problem is I get this error when I click the register button: android app code error
How can I resolve this error ?
Here is my code and other screenshots:
class LoginFragment : Fragment() {
private lateinit var username: EditText
private lateinit var password: EditText
private lateinit var fAuth: FirebaseAuth
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_login, container, false)
username = view.findViewById(R.id.log_username)
password = view.findViewById(R.id.log_password)
fAuth = Firebase.auth
view.findViewById<Button>(R.id.btn_register).setOnClickListener {
val navRegister = activity as FragmentNav
navRegister.navigateFrag(RegisterFragment(),false)
}
view.findViewById<Button>(R.id.btn_login).setOnClickListener {
validateForm()
}
return view
}
private fun firebaseSignIn(){
fAuth.signInWithEmailAndPassword(username.text.toString(),password.text.toString()).addOnCompleteListener{
task ->
if(task.isSuccessful){
}else{
Toast.makeText(context,"Register Successful",Toast.LENGTH_SHORT).show()
var navHome = activity as FragmentNav
navHome.navigateFrag(HomeFragment(),addToStack = true)
}
}
}
private fun validateForm() {
val icon = AppCompatResources.getDrawable(requireContext(), R.drawable.erroricon)
icon?.setBounds(0, 0, icon.intrinsicWidth, icon.intrinsicHeight)
when {
TextUtils.isEmpty(username.text.toString().trim()) -> {
username.setError("Please Enter Username")
}
TextUtils.isEmpty(password.text.toString().trim()) -> {
password.setError("Please Enter Password")
}
username.text.toString().isNotEmpty() &&
password.text.toString().isNotEmpty() -> {
if (username.text.toString().matches(Regex("[a-zA-Z0-9._]+#[a-z]+\\\\.+[a-z]+"))) {
firebaseSignIn()
} else {
username.setError("Please Enter Valid Email Id")
}
}
}
}
I get this error here:
error
FragmentNav {
fun navigateFrag(fragment: Fragment, addToStack:Boolean )
}
Here is the navigation between buttons register/login :
class LoginActivity : AppCompatActivity(R.layout.login_activity),FragmentNav {
private lateinit var fAuth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.login_activity)
fAuth = Firebase.auth
val currentUser = fAuth.currentUser
if(currentUser !=null){
supportFragmentManager.beginTransaction()
.add(com.google.android.material.R.id.container,HomeFragment()).addToBackStack(null)
.commit()
}
supportFragmentManager.beginTransaction()
.add(com.google.android.material.R.id.container,LoginFragment())
.commit()
}
override fun navigateFrag(fragment: Fragment, addToStack: Boolean) {
val transaction = supportFragmentManager
.beginTransaction()
.replace(com.google.android.material.R.id.container,fragment)
if(addToStack){
transaction.addToBackStack(null)
}
transaction.commit()
}
}
That interface is totally useless if you are not passing the MainActivity context to the LoginFragment. Change LoginFragment constructor to this:
class LoginFragment(private val mListener: FragmentNav) : Fragment()
and in onClick() of the register button, call navigateFrag like this:
mListener.navigateFrag(RegisterFragment(),false)
And finally in MainActivity, pass context to LoginFragment like this:
supportFragmentManager.beginTransaction()
.add(com.google.android.material.R.id.container,LoginFragment(this))
.commit()
Fist of all, I am using bottomNavigation which has five fragments on the MainAcitvity .
The problem is down below.
I am using RegisterForActivityResult for gallery image in the fragmentA.
when I use that before changing to other fragments, It's perfectly fine.
However, after changing to different Fragments
and back to the fragmentA then call RegisterForActivityResult again, the callback is not triggered.
when my MainActivity is with in Condition1 I had a problem.
When my MainActivity is with in Condition2 RegisterForActivityResult callback was fine.
condition1----------------------------------------------------------------------
I Initialized fragment variables in the onCreate on MainActivity , and BottomNavigationListener as well.
Condition2----------------------------------------------------------------------
I Initialized fragment variables in the onStart on MainActivity , and BottomNavigationListener as well.
Does anybody know why?
** Problem Code ↓ condition1**
class Main : AppCompatActivity() ,BottomNavigationView.OnNavigationItemSelectedListener {
//viewbinding
private lateinit var binding: Activity4MainBinding
//fragment Verables
private lateinit var homeFragment :Fragment_Home
private lateinit var liveFragment :Fragment_Live
private lateinit var boardFragment :Fragment_Board
private lateinit var chatFragment :Fragment_Chat
private lateinit var mypageFragment :Fragment_Mypage
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = Activity4MainBinding.inflate(layoutInflater)
setContentView(binding.root)
homeFragment = Fragment_Home.newInstance()
liveFragment = Fragment_Live.newInstance()
boardFragment = Fragment_Board.newInstance()
chatFragment = Fragment_Chat.newInstance()
mypageFragment = Fragment_Mypage.newInstance()
binding.bottomNavigationView.setOnNavigationItemSelectedListener(this)
//first fragment when the App started
supportFragmentManager.beginTransaction().add(R.id.main_layout,
homeFragment).commitAllowingStateLoss()
}
override fun onStart() {
super.onStart()
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, homeFragment).commit()
}
R.id.live -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, liveFragment).commit()
}
R.id.board -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, boardFragment).commit()
}
R.id.chat -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, chatFragment).commit()
}
R.id.mypage -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, mypageFragment).commit()
}
}
return true
}
}
** Working Code ↓ condition2**
class Main : AppCompatActivity() ,BottomNavigationView.OnNavigationItemSelectedListener {
//viewbinding
private lateinit var binding: Activity4MainBinding
//fragment Verables
private lateinit var homeFragment :Fragment_Home
private lateinit var liveFragment :Fragment_Live
private lateinit var boardFragment :Fragment_Board
private lateinit var chatFragment :Fragment_Chat
private lateinit var mypageFragment :Fragment_Mypage
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = Activity4MainBinding.inflate(layoutInflater)
setContentView(binding.root)
homeFragment = Fragment_Home.newInstance()
//first fragment when the App started
supportFragmentManager.beginTransaction().add(R.id.main_layout,
homeFragment).commitAllowingStateLoss()
}
override fun onStart() {
super.onStart()
liveFragment = Fragment_Live.newInstance()
boardFragment = Fragment_Board.newInstance()
chatFragment = Fragment_Chat.newInstance()
mypageFragment = Fragment_Mypage.newInstance()
binding.bottomNavigationView.setOnNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, homeFragment).commit()
}
R.id.live -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, liveFragment).commit()
}
R.id.board -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, boardFragment).commit()
}
R.id.chat -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, chatFragment).commit()
}
R.id.mypage -> {
supportFragmentManager.beginTransaction().replace(R.id.main_layout, mypageFragment).commit()
}
}
return true
}
}
FragmentA code↓
class FragmentA : Fragment() {
// binding
lateinit var binding:FragmentABinding
//for instance from outside of the fragment
fun newInstance() : FragmentA{
return FragmentA()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
binding = FragmentABinding.inflate(inflater, container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState)
binding.button.setOnClickListener{
requestImagesFromGallery.launch("image/*")}
}
private val
RequestIamgeFromGallery=registerForActivityResult(ActivityResultContracts.GetContent()) {
//If callback is triggered, returned uri set into the Imageview
binding.mypageImage.setImageURI(uri)
}
}
Please give me some comments why those Fragments instance in the MainActivity onStart work, but onCreate is not working. Also is it ok if I use the condition2?
I am trying to use Hilt on a sample project
but when i compiled my project, i have this sample error message :
Cause: com.example.pokemon.ui.Hilt_MainActivity
This is my activity aclass:
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
private var isFavoriteListVisible = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
supportFragmentManager.beginTransaction()
.replace(R.id.frameLayout, Home())
.commit()
binding?.changeFragment
?.setOnClickListener {
if (isFavoriteListVisible) {
isFavoriteListVisible = false
binding?.changeFragment?.text = "Favorites"
supportFragmentManager.beginTransaction()
.replace(R.id.frameLayout, Home())
.commit()
} else {
isFavoriteListVisible = true
binding?.changeFragment?.text = "Home"
supportFragmentManager.beginTransaction()
.replace(R.id.frameLayout, Favorites())
.commit()
}
}
}
}
What can i do to resolve it or have more details about this issue
I am calling a DialogFragment in another fragment like bellow:
#CoursesFragmentScope
class CoursesFragment : DaggerFragment(),
DefaultLifecycleObserver,
CourseTypeListDialogFragment.ApplySelectedCourseTypeFilter {
#OnClick(R.id.btnCourseType)
fun btnCourseTypeClick() {
val fm = activity!!.supportFragmentManager
val courseTypeListDialogFragment =
CourseTypeListDialogFragment()
courseTypeListDialogFragment.isCancelable = false
courseTypeListDialogFragment.setStyle(
DialogFragment.STYLE_NO_TITLE,
0
)
courseTypeListDialogFragment.setTargetFragment(this, 1)
courseTypeListDialogFragment.show(fm, "")
}
}
And my DialogFragment is like bellow:
class CourseTypeListDialogFragment: DaggerAppCompatDialogFragment(), CourseTypeAdapter.CourseTypeListener {
interface ApplySelectedCourseTypeFilter {
fun applySelectedCourseType()
}
..some code..
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ButterKnife.bind(this, view)
iApplySelectedCourseTypeFilter = targetFragment as ApplySelectedCourseTypeFilter
}
..some code..
}
But get me bellow error in this line:
courseTypeListDialogFragment.setTargetFragment(this, 1)
And say me:
Fragment CourseTypeListDialogFragment{92f4a96 (cbe1689e-1367-4436-8de6-3797320e7d41) } declared target fragment CoursesFragment{422cc09 (9d16e30b-fd71-44a8-8c45-8a866b62c135) id=0x7f0800d5} that does not belong to this FragmentManager!
What can I do?
Both classes are from same package:
import dagger.android.support.DaggerAppCompatDialogFragment
import dagger.android.support.DaggerFragment
I removed courseTypeListDialogFragment.setTargetFragment(this, 1) and opened dialog but not work my interface in dialog.
I am using from fragments in activity like bellow:
class MainActivity : DaggerAppCompatActivity() {
#BindView(R.id.nav_view)
lateinit var navView: BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super<DaggerAppCompatActivity>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
val navController = findNavController(R.id.nav_host_fragment)
navView.setupWithNavController(navController)
navView.menu.findItem(R.id.navigation_courses).setIcon(
IconDrawable(this, MaterialCommunityIcons.mdi_account_box)
.colorRes(R.color.colorPrimaryDark)
.actionBarSize())
navView.menu.findItem(R.id.navigation_login).setIcon(
IconDrawable(this, MaterialCommunityIcons.mdi_login)
.colorRes(R.color.colorPrimaryDark)
.actionBarSize())
}
}
change this line
val fm = activity!!.supportFragmentManager
to
val fm = fragmentManager
read the following blog
https://medium.com/better-programming/what-is-target-fragment-da0e7c7f345c
I have an activity containing an associated view model. The view model loads the data from an online repository. In the same activity I have a table layout containing a viewpager. In the view page are several fragments.
How can I access the activity view model in my fragments?
you can share viewmodel between fragments like this
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}
https://developer.android.com/topic/libraries/architecture/viewmodel
or just make your viewmodel in your activity public then call it in your fragment like:
(activity as MainActivity).viewmodel // MainActivity is your activity