I'm using old way to create bottom navigation and using Fragment as well.
When I starting design some view inside Fragment. Like Edit, TextBox or ScollView etc. Everything in Fragment are unclickable.
(I had run the app on real device and emulator.
I can not use my mouse click the Textbox But I can input the text by using tab to reach the Textbox
Below is the function I use to open Fragment when I clicked navigation
(In my HomeActivity.kt)
private fun openFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
Below is Xml of container
(In my Activity_Home.xml)
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:clickable="true"
android:focusable="true"/>
Below is one of Fragment
class PersonalFragment : Fragment() {
var Personal = getActivity()?.getApplicationContext();
companion object {
fun newInstance(): PersonalFragment = PersonalFragment()
}
override fun onCreateView(inflater: LayoutInflater, container:ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_personal, container, false)
}
}
Below is Xml of 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_green_light">
<Button
android:id="#+id/uploadButton"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="8dp"
android:layout_marginTop="100dp"
android:layout_marginEnd="8dp"
android:background="#drawable/rounded_select_photo_button"
android:text="#string/UploadIMG"
android:textColor="#android:color/white"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/et_nickname"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="8dp"
android:background="#drawable/rounded_etext"
android:ems="10"
android:gravity="center"
android:hint="#string/hint_nickname"
android:importantForAutofill="no"
android:inputType="textPersonName|text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/uploadButton" />
<EditText
android:id="#+id/et_birthday"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="8dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="8dp"
android:background="#drawable/rounded_etext"
android:gravity="center"
android:hint="#string/hint_birthday"
android:importantForAutofill="no"
android:inputType="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.511"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/et_nickname" />
</androidx.constraintlayout.widget.ConstraintLayout>
override onCreateView as follows:
override fun onCreateView(inflater: LayoutInflater, container:ViewGroup?, savedInstanceState: Bundle?): View? {
var view = inflater.inflate(R.layout.fragment_personal, container, false)
var button = view.findViewById(R.id.uploadButton)
button.setOnClickListener(view ->
Toast.makeText(this, "clicked", Toast.LENGTH_LONG).show()
)
return view
}
and rerun the app. by click on Button you should see clicked
Related
I realise this question has been asked previously but the answers provided haven't helped me out. I cannot see what is going wrong here.
I have an activity, in which I display a bottom sheet, the bottom sheet has a title and a recyclerview. The recycler view is only displaying one item, regardless of how many are passed to the adapter. It is possible to scroll through the items but only one at any time is visible.
Here is my activity xml:
<?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"
tools:context=".features.order.automatedcheckout.view.AutomatedCheckoutQRCodeActivity"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/scanBarcodeInstruction"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="50dp"
android:text="Scan the barcode to get started"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/loadingGuideline"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="#+id/progressIndicator"
app:layout_constraintBottom_toTopOf="#+id/loadingGuideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/scanBarcodeInstruction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/qrcodeImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/scanBarcodeInstruction"/>
<TextView
android:id="#+id/tenderName"
app:layout_constraintTop_toBottomOf="#+id/qrcodeImageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/changeTenderButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"
android:visibility="gone"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text = "Change Tender"/>
</androidx.constraintlayout.widget.ConstraintLayout>
and here is my bottom sheet fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bottomSheetLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tenderTitle"
android:layout_marginTop="20dp"
android:layout_marginStart="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SELECT"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/tenderList"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.appcompat.widget.LinearLayoutCompat>
my bottom sheet fragment:
class TenderBottomSheetFragment : BottomSheetDialogFragment() {
private var _binding: FragmentTenderBottomSheetBinding? = null
private val binding get() = _binding!!
private lateinit var onTenderClicks:(tenderDetails: Pair<Int?, String?>) -> Unit
lateinit var adapter: TenderAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentTenderBottomSheetBinding.inflate(inflater, container, false)
adapter = TenderAdapter (
arguments?.parcelableArrayList(ARG_TENDERS)!!,
onTenderClicks
)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val layoutManager = LinearLayoutManager(requireContext())
binding.tenderList.layoutManager = layoutManager
binding.tenderList.addItemDecoration(DividerItemDecoration(requireContext(), layoutManager.orientation))
binding.tenderList.adapter = adapter
}
companion object {
fun newInstance(
campusTenders: List<TenderKt>,
onTenderClick: (tenderDetails: Pair<Int?, String?>) -> Unit
): TenderBottomSheetFragment {
val tenderDialogFragment = TenderBottomSheetFragment()
tenderDialogFragment.onTenderClicks = onTenderClick
tenderDialogFragment.apply {
arguments = Bundle().apply {
putParcelableArrayList(ARG_TENDERS, ArrayList(tenders))
}
}
return tenderDialogFragment
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
I'm sure this is something really simple but unfortunately right now, I'm not seeing it. If anyone could help I would really appreciate it.
UPDATE
Here is the recycler item layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/campus_tender_name"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text ="Flex Account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I have now updated that to:
<TextView
android:id="#+id/campus_tender_name"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:padding="10dp"
tools:text = "Flex Account"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
and that works fine. So it was the constraint layout in the recycler view item
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 want to add dynamic inputs using one fragment, this fragment includes one input and everytime that I click the button the fragment will be insert in the activity layout,
actually I can do it but when I click the button for the second time it's add the fragment input but is overlaps with de old fragment input
inputFragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.InputFragment">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/contInput"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Usuario"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
activity.xml
<?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:id="#+id/cont"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".controller.Activity">
<Button
android:id="#+id/btn"
android:layout_width="324dp"
android:layout_height="81dp"
android:layout_marginTop="82dp"
android:text="Insert input"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.494"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fragment_container"
tools:ignore="MissingConstraints" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="414dp"
android:layout_height="289dp"
android:layout_marginTop="36dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="-2dp" />
</androidx.constraintlayout.widget.ConstraintLayout >
activity.kt
class Activity : AppCompatActivity(){
private var myList = ArrayList<InputFragment>()
private lateinit var binding: ActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btn.setOnClickListener {
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
val nuevoFragmento = InputFragment()
fragmentTransaction.add (R.id.fragment_container, nuevoFragmento)
fragmentTransaction.addToBackStack(null)
fragmentTransaction.commit()
}
}
}
This is not achievable with fragments, when a new fragment is added to the fragment container, the old will not be visible. I will suggest using something that allows list based views such as the Recyclerview. But for a simple small number of inputs, manually hiding inputs and toggling the visibility is the simplest solution
My use case is very simple. I have two fragments which need to communicate using ViewModel:
LoginFragment has a an editable email address field, whose value needs to be received in another fragment, called ProfileFragment. A straightforward transmission of a string field. My idea is to input the email address from LoginFragment, update a shared ViewModel, and then receive the email address in ProfileFragment.
LoginFramgnet 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".LoginFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/editTextTextEmailAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:autofillHints=""
android:backgroundTint="#FF9393"
android:ems="10"
android:hint="#string/email"
android:inputType="textEmailAddress"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btnLogin"
android:layout_width="200dp"
android:layout_height="50dp"
android:background="#FFFDD2B5"
android:text="#string/login"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/editTextTextPassword"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="#+id/editTextTextPassword"
app:layout_constraintTop_toBottomOf="#+id/editTextTextPassword"
app:layout_constraintVertical_bias="0.37" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
LoginFragment.kt
class LoginFragment : Fragment() {
private lateinit var viewModel: LoginFragmentViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(LoginFragmentViewModel::class.java)
btnLogin.setOnClickListener {
Toast.makeText( activity,"${editTextTextEmailAddress.text} is logged in!!", Toast.LENGTH_SHORT).show()
viewModel.setEmailAddress("${editTextTextEmailAddress.text}")
Log.i("Info", "${viewModel.emailAddress.value}")
view.findNavController().navigate(R.id.action_loginFragment_to_profileFragment)
}
ViewModel.kt:
class LoginFragmentViewModel : ViewModel() {
val emailAddress = MutableLiveData<Any>()
fun setEmailAddress(email:String){
emailAddress.value = email
}
}
ProfileFragment 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=".ProfileFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtEmailAddress"
android:layout_width="260dp"
android:layout_height="144dp"
android:text=""
android:textSize="14sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
ProfileFragment.kt:
class ProfileFragment : Fragment() {
private lateinit var viewModel: LoginFragmentViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this).get(LoginFragmentViewModel::class.java)
viewModel.emailAddress.observe(viewLifecycleOwner, object : Observer<Any>{
override fun onChanged(t: Any?) {
txtEmailAddress.text = t!!.toString()
}
})
Log.i("Info", "${viewModel.emailAddress.value}")
}
The Log on LoginFragment registers that the emailAddress in the ViewModel is changed, based on what is input in the editTextTextEmailAddress.
The Log on ProfileFragment returns "null".
What exactly am I doing wrong?
You have two different ViewModel instances bound to two different ViewModelStores (represented as fragments). If you need a shared ViewModel, then you need to use a single ViewModelStore. I believe that changing ViewModelProvider(this) to ViewModelProvider(requireActivity()) for both fragments will do the trick, but you will need to find out for yourself if it's suitable for your design.
fragment_news_details
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data class="NewsDetailsBinding">
<variable
name="adapter"
type="com.abc.xyz.base.BaseAdapter" />
</data>
<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=".news.NewsDetailsFragment">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/viewPagerGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.4" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/imageViewPager"
android:layout_width="0dp"
android:layout_height="0dp"
android:adapter="#{adapter}"
app:layout_constraintBottom_toBottomOf="#id/viewPagerGuideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/dotsTab"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="#color/transparent"
app:layout_constraintBottom_toBottomOf="#id/imageViewPager"
app:layout_constraintEnd_toEndOf="#+id/imageViewPager"
app:layout_constraintStart_toStartOf="#+id/imageViewPager"
app:tabBackground="#drawable/dot_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp" />
<TextView
android:id="#+id/descriptionTitleTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="#color/textColorPrimary"
android:textSize="#dimen/text_size_20"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/viewPagerGuideline"
tools:text="Fresh snow at Dunga" />
<TextView
android:id="#+id/descriptionTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="#color/textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/descriptionTitleTV"
tools:text="Lorem ipsum dolor sit." />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout><?xml version="1.0" encoding="utf-8"?>
NewsDetailsFragment
class NewsDetailsFragment : Fragment() {
lateinit var binding: NewsDetailsBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = inflater.bind(R.layout.fragment_news_details, container)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val templist = ArrayList<String>().apply {
add("https://picsum.photos/id/237/200/300")
add("https://picsum.photos/seed/picsum/200/300")
add("https://picsum.photos/id/1002/300/400")
add("https://picsum.photos/id/237/200/300")
}
binding.adapter =
BaseAdapter(templist, R.layout.item_news_image, ::NewsImageViewHolder)
if (binding.adapter != null)
TabLayoutMediator(binding.dotsTab, binding.imageViewPager) { tab, position ->
tab.icon = ContextCompat.getDrawable(requireContext(), R.drawable.anim_add_star)
}.attach()
}
inner class NewsImageViewHolder(itemBinding: NewsImageItemBinding) :
BaseViewHolder<String, NewsImageItemBinding>(itemBinding) {
}
}
in on activity created its throwing error TabLayoutMediator attached before ViewPager2 has an adapter. I tried adding the adapter above and below the TabloutMediatorI().attach(), does not work in both cases.What I need is to show dots indicator using tabslayout .I am new using ViewPager 2 ,Any help would be appreciated.Thanks.
ViewPager doesn't have an adapter attribute, so android:adapter="#{adapter}" doesn't set the adapter on the ViewPager.
Instead, you can get the view pager from binding and set the adapter in your fragment like this: binding.imageViewPager.adapter = BaseAdapter(templist, R.layout.item_news_image, ::NewsImageViewHolder)