I have a fragment with an xml file. The xml file tries to include an other xml file. When I try to use binding, to set different variables of the included xml, nothing happens. Here is my code:
fragment xml (short version):
<include
android:id="#+id/include2"
layout="#layout/sende_option_box"
android:layout_width="0dp"
android:layout_height="147dp"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
app:title='#{"foo"}'
app:numbervalue='#{"foo"}'
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView25" />
Included xml:
<layout>
<data>
<variable name="title" type="String" />
<variable name="numbervalue" type="String" />
</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="147dp"
android:background="#drawable/parcel_list_item_borderbox"
android:elevation="5dp">
<TextView
android:id="#+id/textView26"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:layout_marginTop="33dp"
android:text="#{title}"
android:textAppearance="#style/TextAppearanceBoldBody22"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Opptil 10kg"/>
<TextView
android:id="#+id/textView27"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:text="Norgespakken"
android:textAppearance="#style/TextAppearanceBody15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView26" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:layout_marginBottom="15dp"
android:background="#color/postenVeryLightPink"
android:padding="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="#+id/textView28"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{numbervalue}"
android:textAppearance="#style/TextAppearanceBoldBody15"
android:textColor="#color/postenPrimaryDark"
tools:layout_editor_absoluteX="50dp"
tools:layout_editor_absoluteY="17dp"
tools:text="Fra 149,-"/>
</LinearLayout>
<ImageView
android:id="#+id/imageView6"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginEnd="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/alert_message_borderbox_yellow" />
</androidx.constraintlayout.widget.ConstraintLayout>
The build runs, but there is no foo showing in the view as I wanted it to. What am I doing wrong? Is it because of its a fragment?
You have to call DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main) in Your layout file where layout is included. Example:
included_layout:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<variable
name="myTitle"
type="String"/>
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{myTitle}"/>
</layout>
main_activity:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/included_layout"
app:myTitle="#{`Your Title`}" />
</LinearLayout>
</layout>
MainActivty:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.myniprojects.bindingtest.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main) // HERE You have to call this function
}
}
If You include layout in fragment You call the same function in onCreateView but not with this but requireActivity and of course as 2nd argument You pass right XML layout. In fragment You can call this function and return value:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return DataBindingUtil.setContentView<FragmentBlankBinding>(
requireActivity(),
R.layout.fragment_blank
).root
}
Related
Im trying to get layouts with merge root tag to work with view binding. I have a main_acticity that include the merge layout with an id
this is my merge_layout
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="#+id/merge_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center|bottom"
android:layout_marginBottom="40dp"
android:src="#drawable/test"/>
<Button
android:id="#+id/merge_test_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/merge_test_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="5dp"
android:textColor="#fff"
android:textSize="12sp" />
</FrameLayout>
</merge>
this is my include_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
//---->My Stuff<----
<include
android:id="#+id/merge_layout"
layout="#layout/merge_layout" />
</FrameLayout>
And the main activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = IncludeLayoutBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.mergeLayout.mergeTestButton.setOnClickListener {
//Toast.makeText(this, "it work!!!", Toast.LENGTH_SHORT).show()
}
Runtime exception: Missing required view with ID: mergeLayout
I want to know if is there any way to bind merge using an id in the include tag, like the example
When you use a merge tag in the root of a layout that you're going to include, don't put the id in the include tag.
activity layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/marge_layout" />
</FrameLayout>
your marge layout which you went to include in activity
<?xml version="1.0" encoding="utf-8"?>
<merge 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="wrap_content">
<FrameLayout
android:id="#+id/merge_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center|bottom"
android:layout_marginBottom="40dp"
android:src="#drawable/ic_share_app"/>
<Button
android:id="#+id/merge_test_button"
android:layout_height="wrap_content"
android:text="Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"/>
<TextView
android:id="#+id/merge_test_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="5dp"
android:textColor="#fff"
android:textSize="12sp" />
</FrameLayout>
</merge>
then your activity code like below
class MainActivity : AppCompatActivity() {
#SuppressLint("AndroidCustomToast")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityTempBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
val margeLayout = MargeLayoutBinding.bind(binding.root)
margeLayout.mergeTestButton.setOnClickListener {
Toast.makeText(this, "it work!!!", Toast.LENGTH_SHORT).show()
}
}
}
I have a Constraint layout which 2 main elements inside it: a nested scroll view with a list of elements defined inside another layout file and a textview used as a footer.
This is the 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:id="#+id/menu_scrollview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:context=".sections.main.menu.MenuFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/menu_title"
style="#style/AppTheme.TextTitle1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/mid_small_margin"
android:text="#string/menu_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include layout="#layout/list_item_menu_fragment" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<TextView
android:id="#+id/menu_title_2"
style="#style/AppTheme.TextTitle1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/mid_small_margin"
android:text="#string/menu_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the list_item_menu_fragment.xml layout defined in it:
<?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"
android:id="#+id/menu_elements_list"
style="#style/RectangularTextViewMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="#dimen/mid_small_margin"
android:layout_marginTop="20dp"
android:layout_marginBottom="32dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="#+id/menu_item_profile"
app:layout_constraintBottom_toBottomOf="#+id/links_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/charge_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:fontFamily="#font/montserrat_bold"
android:gravity="center_vertical"
android:textColor="#color/black"
android:text="#string/menu_pay_charge"
app:drawableStartCompat="#drawable/ic_menu_charge"
app:drawableEndCompat="#drawable/ic_arrow_right" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/pay_online_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:fontFamily="#font/montserrat_bold"
android:gravity="center_vertical"
android:textColor="#color/black"
android:text="#string/menu_pay_online"
app:drawableStartCompat="#drawable/ic_menu_pay_online"
app:drawableEndCompat="#drawable/ic_arrow_right" />
</LinearLayout>
This is my fragment:
class MenuFragment : Fragment() {
private var _binding: FragmentMenuBinding? = null
private val menuViewModel by viewModels<MenuViewModel>()
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMenuBinding.inflate(inflater, container, false)
return binding.root
}
If I tryo access to my list of elements using binding.chargeButton it says that i cannot do it (because it is in another layout). If I do binding.menuTitle it works perfectly. How can I access to those elements?
As written in ViewBinding
An instance of a binding class contains direct references to all views
that have an ID in the corresponding layout.
You have to assign an ID to the included layout and then you can call it from the parent view binding class.
Change from
<include layout="#layout/list_item_menu_fragment" />
to
<include android:id="#+id/listItemMenu" layout="#layout/list_item_menu_fragment" />
Now you can call binding.listItemMenu.chargeButton
Not sure if I messed up or if I should file a bug report with Google. Probably I messed up.
My app has the nav host (and nav drawer) in MainActivity and a view pager and tabs in a fragment. When the fragment that hosts the viewpager gets loaded the viewpager is the same size as the contents of the first fragment at the first tab. When I click on another tab to load a fragment with much more content into the viewpager, the content of fragment 2 is clipped to the size and position of the content of fragment one. If I then use the options menu to go to a different fragment and then back again with the <- button, then the second fragment is displayed correctly. What I need is for every fragment to display correctly every time regardless. In fact, I want the viewpager content to fill up the available space even if the fragment being loaded is smaller than the available space. I have tried setting every height attribute I can find to "match_parent" instead of "wrap_content", but no luck. The "design" view of the layout editor listed "0dp" as "match constraint" but when I tried that it vanished altogether. Help greatly appreciated.Screenshot of before and after using <- button
Code for fragment class hosting ViewPager 2:
class PagerHostFragment : Fragment() {
private lateinit var binding: FragmentPagerHostBinding
private lateinit var viewPager: ViewPager2
private lateinit var tabTitleList: List<String>
private lateinit var tabLayout: TabLayout
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
super.onCreateView(inflater, container, savedInstanceState)
binding = FragmentPagerHostBinding.inflate(inflater, container, false)
tabLayout = binding.tabs
viewPager = binding.pager
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//have also tried activity instead of getActivity(). same result
val pagerAdapter = ViewPagerAdapter(getActivity())
viewPager.adapter = pagerAdapter
tabTitleList = listOf(
(getString(R.string.tab_title_first)),
(getString(R.string.tab_title_second)),
(getString(R.string.tab_title_third))
)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = tabTitleList[position]
}.attach()
}
}
Code for Adapter class
class ViewPagerAdapter(fa: FragmentActivity?) : FragmentStateAdapter(fa!!) {
private val tabbedFragments: Array<Fragment> = arrayOf(
FirstFragment(),
SecondFragment(),
ThirdFragment()
)
override fun getItemCount(): Int {
return tabbedFragments.size //Number of fragments displayed
}
// this is flagged by Android Studio as redundant but it's here because a previous
// answer put it in. I've tried with and without, same result
override fun getItemId(position: Int): Long {
return super.getItemId(position)
}
override fun createFragment(position: Int): Fragment {
return tabbedFragments[position]
}
}
XML for fragment hosting tabs and pager
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:context=".ui.PagerHostFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabIndicatorHeight="48dp">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="102dp"
android:foregroundGravity="bottom"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
XML for first fragment loaded on first tab
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.FirstFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Frag"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
XML for second fragment loaded on second tab
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.SecondFragment">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button1" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button2" />
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button3" />
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button4" />
<Button
android:id="#+id/button6"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button5" />
<Button
android:id="#+id/button7"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button6" />
<Button
android:id="#+id/button8"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button7" />
<Button
android:id="#+id/button9"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button8" />
<Button
android:id="#+id/button10"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button9" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Classes associated with all 3 fragments that are loaded into the pager adapter are only boilerplate, I'm just trying to get the UI working right. XML for the 3rd fragment is identical to the first except for name and text view content.
Edited to add: Setting ViewPager2 minHeight to 426 did not change anything. Shouldn't the viewpager match in size whatever it's displaying, automatically? Is this a bug or have I done this wrong?
I try setting value to include layout.
I wrapped the root layout to tag and passed using app:headerTitle.
But I got this error
AAPT: C:\Users\ckdrb\Desktop\EMOPlayer\app\build\intermediates\incremental\mergeDebugResources\stripped.dir\layout\activity_equalizer.xml:11: error: attribute headerTitle (aka com.jakchang.emo:headerTitle) not found.
error: failed linking file resources.
I don't understand what's wrong, Because I followed so many examples.
equalizer.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/player_background_theme"
android:orientation="vertical">
<include
android:id="#+id/appbar"
layout="#layout/layout_part_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:headerTitle="bas123"/>
</LinearLayout>
</layout>
layout_part_appbar.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="headerTitle"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/loginHeaderLayout"
android:layout_width="match_parent"
android:layout_height="56dp">
<Button
android:id="#+id/backButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="5dp"
android:background="#drawable/back_arrow_black"
app:backgroundTint="#null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/headerTitleText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textAlignment="center"
android:textSize="#dimen/appbar_title_text_size"
android:textStyle="bold"
android:textColor="#color/colorBlack"
android:layout_marginStart="10dp"
android:text="#{headerTitle}"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/backButton"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
To pass the value using data binding you need to set it as below
app:headerTitle="#{`bas123`}"
In the data section, you need to use fully qualified path or import the class, like in Java.
Using full path:
<data>
<variable
name="headerTitle"
type="java.lang.String" />
</data>
Using import:
<data>
<import type="java.lang.String"/>
<variable
name="headerTitle"
type="String" />
</data>
I have achieved this via code. First remove app:headerTitle="bas123" declared inside equalizer.xml. Then in fragment or activity set data to variable headerTitle. Look below code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<EqualizerBinding>
(this,R.layout.equalizer)
binding.appbar.headerTitle = "My Header"
}
Like app:headerTitle="#{#string/app_name}" in equalizer.xml file
In order to show a BottomSheetBehavior i need to pass his view like below.
ViewUtil.kt class
fun showBottomSheet(view: View) {
val bottomSheetBehavior = BottomSheetBehavior.from(view)
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
} else {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
}
}
Fragment.kt
termsTitle.setOnClickListener {
showBottomSheet(tosLayoutBottomSheet)
}
bottom_sheet_tos.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/tosLayoutBottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="#string/bottom_sheet_behavior">
<!-- some stuff about terms of service -->
</androidx.constraintlayout.widget.ConstraintLayout>
fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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:ignore="MissingDefaultResource">
<data>
<import
alias="v"
type="android.view.View" />
<variable
name="fragmentViewModel"
type=".FragmentViewModel"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_main_page">
<TextView
android:id="#+id/terms_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="24dp"
android:layout_marginBottom="8dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:text="#string/terms_of_service"
android:textColor="#color/colorGrey"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
So, instead use onclicklistener from fragment I would like to do it from my xml and viewmodel like:
fragment.xml
<TextView
android:id="#+id/terms_title"
android:onClick="#{(v)-> fragmentViewModel.showBottomSheetFrag(tosLayoutBottomSheet)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="24dp"
android:layout_marginBottom="8dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:text="#string/terms_of_service"
android:textColor="#color/colorGrey"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
I know the above approach not work because tosLayoutBottomSheet id is in another layout. How can I pass an id from a different layout ?
A bit late but you can add an import of R class in your xml file and then pass the view id with R.id.view_id
<import type="com.xxx.xxxx.R" />
then in you onclick
android:onClick="#{(v)->view.yourMethod(R.id.view_id)}"