I have an activity MainActivity in which I have and fragment signup_fragment I want to call fragment from an activity but it gives an exception of Binary XML file line #23: Binary XML file line #23: Error inflating class fragment
and Caused by: java.lang.RuntimeException: com.example.pickingredients.MainActivity#d9ff1e7 must implement OnFragmentInteractionListener
Below are my code
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragment=Signup()
supportFragmentManager.beginTransaction().add(R.id.sigup_fragment,fragment).commit()
}
SignupFragment
class Signup : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private var listener: OnFragmentInteractionListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_signup, container, false)
}
// TODO: Rename method, update argument and hook method into UI event
fun onButtonPressed(uri: Uri) {
listener?.onFragmentInteraction(uri)
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnFragmentInteractionListener) {
listener = context
} else {
throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
}
}
override fun onDetach() {
super.onDetach()
listener = null
} }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#color/light_grey">
<TextView
android:text="#string/what_is_your_mood"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/mood_tv"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintHorizontal_bias="0.03"
android:layout_marginTop="16dp" app:layout_constraintTop_toTopOf="parent"
android:textSize="18sp"/>
<androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="#+id/guideline" app:layout_constraintGuide_begin="16dp"
android:orientation="vertical"/>
<fragment
android:layout_width="362dp"
android:layout_height="98dp" android:name="com.example.pickingredients.ImagesliderFragment"
android:id="#+id/sigup_fragment" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" app:layout_constraintStart_toStartOf="#+id/guideline"
android:layout_marginStart="8dp" app:layout_constraintTop_toBottomOf="#+id/mood_tv"
android:layout_marginTop="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_signup.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Signup">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"/>
</FrameLayout>
Just remove android:name tag from <fragment .../>..
And use FrameLayout instead of fragment.
Or you can use below code.
<FrameLayout
android:layout_width="362dp"
android:layout_height="98dp"
android:id="#+id/sigup_fragment"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#+id/guideline"
app:layout_constraintTop_toBottomOf="#+id/mood_tv" />
Problem is here com.example.pickingredients.ImagesliderFragment. Either this fragment not found or having issues on that fragment.
And you should use FrameLayout instead of Fragment in xml.
Moreover your MainActivity should implement OnFragmentInteractionListener
Related
I have seen similar questions here, but none of them helps.
I have MainActivity and a few Fragments which works fine, but I want to set one fragment inside of another.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomMenu)
val hostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as NavHostFragment
val navigationController = hostFragment.navController
bottomNavigationView.setupWithNavController(navigationController)
setupActionBarWithNavController(navigationController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragmentContainer)
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
Parent Fragment:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
incomeButton = view.findViewById(R.id.addIncomeButton)
expenseButton = view.findViewById(R.id.addExpenseButton)
val childFragment: Fragment = ChartFragment()
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.childFragment, childFragment).commit()
return view
}
Child Fragment:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return ComposeView(requireContext()).apply {
setContent {
Text(
text = "here is another important code",
fontSize = 28.sp
)
}
}
The layouts for Activity:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomMenu"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:menu="#menu/bottom_menu" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainer"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="475dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottomMenu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_map" />
</androidx.constraintlayout.widget.ConstraintLayout>
The layouts for Fragment:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.MainFragment">
<Button
android:id="#+id/addIncomeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="21dp"
android:layout_marginBottom="21dp"
android:backgroundTint="#color/primary"
android:text="#string/addIncomeButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="#+id/addExpenseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="21dp"
android:layout_marginBottom="10dp"
android:backgroundTint="#color/red"
android:text="#string/addExpenseButton"
app:layout_constraintBottom_toTopOf="#+id/addIncomeButton"
app:layout_constraintEnd_toEndOf="parent" />
<FrameLayout
android:id="#+id/forChart"
android:layout_width="match_parent"
android:layout_height="350dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The most of the same questions' solvations say to use childFragmentManager so do I but it doesn't work.
I get an error java.lang.IllegalArgumentException: No view found for id 0x7f08023f.
I guess I do not understand something, but I can't realize what.
Thank you!
Seems that you're mixing the ids of the container for the transaction - that's also what the error says. You're trying to put the ChartFragment into a container with R.id.childFragment id:
transaction.replace(R.id.childFragment, childFragment).commit()
And from what I see in the MainFragment layout, the container id is R.id.forChart. Try changing it to this:
transaction.replace(R.id.forChart, childFragment).commit()
I looked at past questions but i can't still solve my problem
I am getting this error : java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment
My MainActivity code is :
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController =navHostFragment.navController
val navBottomView: BottomNavigationView = findViewById(R.id.bottomNavigation)
navBottomView.setupWithNavController(navController)
}
}
My HomeFragment code is this
class HomeFragment : Fragment() {
private var activity: MainActivity?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity = activity
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view : View = inflater.inflate(R.layout.fragment_home,container,false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
ActivityMain.xml code is here too :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/app_bar_layout" >
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graoh" />
</FrameLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<androidx.appcompat.widget.Toolbar
android:id="#+id/dashboard_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#android:color/white">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
android:layout_marginRight="15dp"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
I can't run my app. If some one can help me it will be perfect
The problem is in the MainActivity where you do not have setContentView(R.id.activity_main)
extra notes I have noticed
in your homeFragment you have:
activity = activity // which is self assign
and in your main activity xml you have a typo in the following line:
app:navGraph="#navigation/nav_graoh"
and you are missing the closing tag of relative layout
In MainActivity.kt, add the button function, it can't run.
How to solve?
Thank!
add the button function, it can't run.
binding.button1.setOnClickListener {
binding.text.text = "123"
}
drive.google.com
Source code
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#702020" />
<TextView
android:id="#+id/text"
android:text="text"
android:textSize="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<fragment
android:id="#+id/nav_host_fragment"
android:name="com.android.myapplication.Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_"
/>
</LinearLayout>
fragment_.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment">
</FrameLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
val binding: ActivityMainBinding by viewbind()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding.button1.setOnClickListener {
binding.text.text = "123"
}
}
}
Fragment.kt
class Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_, container, false)
}
error code
enter image description here
Add below Gradle dependency
implementation "androidx.fragment:fragment-ktx:1.3.1"
Replace <fragment> with following code
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="com.android.myapplication.Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_" />
another replace in MainActivity.kt
class MainActivity : AppCompatActivity() {
val binding: ActivityMainBinding by viewbind()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.nav_host_fragment, com.android.myapplication.Fragment())
fragmentTransaction.show(com.android.myapplication.Fragment())
fragmentTransaction.commit()
binding.button1.setOnClickListener {
binding.text.text = "123"
}
In my activity I have one FrameLayout that needs to be swapped out with another fragment on button press. When the second fragment is pushed, the actionbar does not show the back arrow. However, pressing the back triangle does pop the second fragment and returns to the Main Fragment.
The initial Activity with the Main fragment
You can see that the second fragment is added, but the arrow is not present to take the user back. Even though in my NewCallFragment I have the line
activity?.actionBar?.setDisplayHomeAsUpEnabled(true)
What am I doing wrong?
My Activity
private const val TAG = "DashboardActivity"
class DashboardActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dashboard)
if (savedInstanceState == null) {
supportFragmentManager.commit { add<MainFragment>(R.id.fragment_container, null, intent.extras) }
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putCharSequence(TAG, title)
}
override fun onSupportNavigateUp(): Boolean {
if (supportFragmentManager.popBackStackImmediate()) {
return true
}
return super.onSupportNavigateUp()
}
class MainFragment : Fragment(R.layout.fragment_dashboard_main) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.btnNewCall).setOnClickListener {
onShowNewCall()
}
}
private fun onShowNewCall() {
activity?.supportFragmentManager?.commit {
replace<NewCallFragment>(R.id.fragment_container, null, null)
addToBackStack(null)
}
}
}
class NewCallFragment : Fragment(R.layout.fragment_new_call) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity?.actionBar?.setDisplayHomeAsUpEnabled(true)
activity?.title = "My Second Fragment"
}
}
}
Activity Layout
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/dashboard_root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" android:padding="#dimen/parent_padding"
tools:context=".activitiesx.DashboardActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Main Fragment Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="#+id/btnNewCall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:paddingTop="10sp"
android:paddingBottom="10sp"
android:text="#string/new_call"
app:icon="#drawable/ic_add" />
</RelativeLayout>
New Call Fragment Layout
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add new call"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I'm getting a "type mismatch required OnQueryTextListener!" error when trying to implement searchview in Kotlin in a Navigation Fragment. I've searched as many samples and stackoverflow questions as I could and everything says my code should be correct. Note that my searchview is PERSISTANT (not part of the menu), so I cannot do a menu.finditem.
Here is my HomeFragment code :
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
println("***************** Home Fragment *******************")
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
// task HERE
return false
}
override fun onQueryTextChange(newText: String): Boolean {
return false
}
})
}
and the layout code:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/materialBackgroundGrey">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:iconifiedByDefault="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:queryBackground="#null">
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search"
app:iconifiedByDefault="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.cardview.widget.CardView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#color/colorWhite"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView"
app:layout_constraintBottom_toBottomOf="parent"
/>
There are two SearchView widgets:
android.widget.SearchView
androidx.appcompat.widget.SearchView
These fill the same role but are not compatible, and their nested interfaces, like OnQueryTextListener, are not compatible.
Make sure that you use the same one both in resources (such as your layout) and in any import statements. If you are using AppCompat, you probably want androidx.appcompat.widget.SearchView.