I've been search the entire internet or couple of hours, no luck
I'm trying to figure out how to pass in the MutableLiveData to a custom view
Here is the live data in the ViewModel for my activity data binding
var perStops: MutableLiveData<Int> = MutableLiveData(10)
Here is how I use the custom view in my activity
<com.abc.ui.widgets.NumberStepper
app:amount="#={data.perStops}"
app:min="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"/>
This is the custom view for the number stepper
class NumberStepper(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) {
private val rootView = LayoutInflater.from(context)
val binding = NumberPickerCustomLayoutBinding.inflate(rootView,this,true)
init {
val customAttributes = context.obtainStyledAttributes(attrs, R.styleable.NumberStepper)
val minAmount = customAttributes.getInteger(R.styleable.NumberStepper_min,0)
val amount = customAttributes.getInteger(R.styleable.NumberStepper_amount,0)
binding.suffix = customAttributes.getString(R.styleable.NumberStepper_suffix)?:""
binding.data = amount
}}
Here is the XML layout for NumberPickerCustomLayoutBinding
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="Integer" />
<variable
name="suffix"
type="String" />
</data>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="horizontal">
<ImageButton
android:id="#+id/decrement"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="-10dp"
android:background="#null"
android:padding="#dimen/odc_padding16"
android:src="#drawable/ic_minus" />
<TextView
android:id="#+id/display"
style="#style/TextAppearance.Secondary"
android:layout_width="45dp"
android:layout_height="match_parent"
android:background="#android:color/white"
android:gravity="center"
tools:text="1"
android:text='#{data.toString() + suffix}' />
<ImageButton
android:id="#+id/increment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="-10dp"
android:background="#null"
android:padding="#dimen/odc_padding16"
android:src="#drawable/ic_plus" />
</LinearLayout>
Related
I am trying to build a layout in which there is a recyclerview where each item has three edittexts horizontally aligned. I want to add the next item when a button is pressed.
This the design I am trying to build
This is the Adapter class for the recycler view
class AddProjectAdapter(private val itemsList : ArrayList<ItemDetails>) : RecyclerView.Adapter<AddProjectAdapter.AddProjectViewHolder>() {
inner class AddProjectViewHolder(private val binding : AddProjectItemViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(item : ItemDetails){
binding.item = item
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddProjectViewHolder{
return AddProjectViewHolder(AddProjectItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: AddProjectViewHolder, position: Int) {
holder.bind(itemsList[position])
}
override fun getItemCount(): Int = itemsList.size
}
Layout file for the item add_project_item_view.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="item"
type="com.example.hero.models.ItemDetails" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="#+id/item_name_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="3"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="#id/g_v_1"
android:layout_marginRight="5dp">
<EditText
android:id="#+id/item_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Item Name"
android:text="#={item.itemName}"
android:textColor="#color/t_dark"
android:fontFamily="#font/metropolislight"
android:textSize="14dp"
android:textColorHint="#color/t_dark"
android:background="#null"
android:padding="10dp" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/rate_unit_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="2"
android:layout_marginRight="5dp"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toEndOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_2">
<EditText
android:id="#+id/rate_unit_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Rate/Unit"
android:text="#={item.rate}"
android:textColorHint="#color/t_dark"
android:textColor="#color/t_dark"
android:fontFamily="#font/metropolislight"
android:textSize="14dp"
android:padding="10dp"
android:background="#null" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/unit_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="2"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toEndOf="#id/g_v_2"
app:layout_constraintEnd_toEndOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/unit_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="#null"
android:fontFamily="#font/metropolislight"
android:hint="Unit"
android:padding="10dp"
android:text="#={item.unit}"
android:textColor="#color/t_dark"
android:textColorHint="#color/t_dark"
android:textSize="14dp" />
<ImageView
android:id="#+id/drop_down_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="#drawable/dropdown"
android:layout_centerVertical="true" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.4" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
`
//code of the activity in which the recycler view is present
private val itemsList : ArrayList<ItemDetails> = ArrayList()
private lateinit var addProjectAdapter: AddProjectAdapter
private lateinit var binding: ActivityAddProjectBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAddProjectBinding.inflate(layoutInflater)
setContentView(binding.root)
setAdapter()
setListner()
}
private fun setAdapter(){
addProjectAdapter = AddProjectAdapter(itemsList)
binding.itemDetailsRecyclerview.apply {
layoutManager = LinearLayoutManager(this#AddProject)
adapter = addProjectAdapter
}
}
override fun onClick(v : View?) {
when(v?.id){
binding.addItemButton.id -> {
itemsList.add(ItemDetails())
addProjectAdapter.notifyItemInserted(itemsList.size-1)
}
}
}
private fun setListner(){
binding.addItemButton.setOnClickListener(this)
}
data class ItemDetails(
var itemName : String = "",
var rate : String = "",
var unit : String = "")
And my recyclerview id is item_details_recyclerview.
Output for the above code
When I click the add button the item added is not visible but the add button moves down.
Can someone help me out with this issue? And also if you could provide some better approach it would be great.
Thanks in advance.
Change height of ConstraintLayout from add_project_item_view.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
to this
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
I am working on an application with multiple recycler views inside a fragment. Everything is working properly, except from one recycler view which doesn't display all data. I get the data after an API call, and I have already checked that they are loaded successfully. Any help would be much appreciated, thank you in advance!!
Here is the recycler view inside the fragment:
<?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="wrap_content"
android:background="#color/white"
tools:context=".ui.fragments.ExploreFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:fillViewport="true"
android:scrollbars="none">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvExploreFragmentFeaturedProducts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
>
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
Here is the cardview which will be loaded repeatedly inside the recycler view, which is not properly displayed (only the image view and shapeable image view gets displayed):
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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/layoutFeaturedProductRowCardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
android:layout_marginBottom="40dp">
<RelativeLayout
android:id="#+id/rlFeaturedProducts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#drawable/rounded_frame_recommproducts_explore">
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/ivFeaturedProduct"
android:layout_width="335dp"
android:layout_height="180dp"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="#style/rounded_cornersTop"
tools:src="#tools:sample/backgrounds/scenic" />
<ImageView
android:id="#+id/imageViewFavorite"
android:layout_width="wrap_content"
android:layout_height="26dp"
android:layout_alignEnd="#id/ivFeaturedProduct"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:src="#drawable/ic_favorite_up"/>
<TextView
android:id="#+id/textViewProductTitle"
android:layout_width="295dp"
android:layout_height="wrap_content"
android:layout_below="#+id/ivFeaturedProduct"
android:layout_marginStart="15dp"
android:layout_marginTop="20dp"
android:fontFamily="#font/semibold"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="16sp" />
<TextView
android:id="#+id/textViewCategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textViewProductTitle"
android:layout_alignStart="#id/textViewProductTitle"
android:fontFamily="#font/semibold"
android:textSize="12sp"/>
<TextView
android:id="#+id/textViewDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textViewCategory"
android:layout_alignStart="#id/textViewCategory"
android:layout_marginTop="20dp"
android:drawablePadding="10dp"
android:fontFamily="#font/medium"
android:text="#string/durationlabel"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="12sp"
app:drawableLeftCompat="#drawable/ic_time_icon" />
<TextView
android:id="#+id/textViewDurationValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/textViewDuration"
android:layout_alignBaseline="#id/textViewDuration"
android:layout_marginStart="2dp"
android:fontFamily="#font/medium"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="12sp"/>
<TextView
android:id="#+id/textViewLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textViewDuration"
android:layout_alignStart="#id/textViewDuration"
android:layout_marginTop="12dp"
android:drawablePadding="10dp"
android:fontFamily="#font/medium"
android:text="#string/languagelabel"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="12sp"
app:drawableLeftCompat="#drawable/ic_audio_icon" />
<TextView
android:id="#+id/textViewLanguageValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/textViewLanguage"
android:layout_alignBaseline="#id/textViewLanguage"
android:layout_marginStart="2dp"
android:fontFamily="#font/medium"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="12sp" />
<TextView
android:id="#+id/textViewThreeSixtyImages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textViewLanguage"
android:layout_alignStart="#id/textViewLanguage"
android:layout_marginTop="12dp"
android:drawablePadding="10dp"
android:fontFamily="#font/medium"
android:text="#string/theesixtylabel"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="12sp"
app:drawableLeftCompat="#drawable/ic_images_icon"
android:visibility="gone"/>
<TextView
android:id="#+id/ratingLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#id/ratingValue"
android:layout_toStartOf="#id/ratingValue"
android:layout_marginTop="2dp"
android:drawablePadding="10dp"
android:fontFamily="#font/semibold"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="14sp"
app:drawableLeftCompat="#drawable/ic_rating_small_tag" />
<TextView
android:id="#+id/ratingValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="#id/ratingCount"
android:layout_alignBaseline="#id/ratingCount"
android:layout_marginEnd="2dp"
android:fontFamily="#font/semibold"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="14sp"
/>
<TextView
android:id="#+id/ratingCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/ivFeaturedProduct"
android:layout_alignTop="#id/textViewCategory"
android:layout_alignRight="#id/ivFeaturedProduct"
android:layout_marginEnd="15dp"
android:fontFamily="#font/semibold"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="14sp" />
<TextView
android:id="#+id/priceLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/ratingCount"
android:layout_alignEnd="#id/ratingCount"
android:layout_marginTop="20dp"
android:fontFamily="#font/medium"
android:text="#string/fromLabel"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="12sp" />
<TextView
android:id="#+id/salesValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/priceLabel"
android:layout_below="#id/priceLabel"
android:layout_marginTop="2dp"
android:fontFamily="#font/medium"
android:textSize="12sp"
android:textColor="#color/colorPrimaryV2"
android:visibility="gone"/>
<TextView
android:id="#+id/priceValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/priceLabel"
android:layout_alignEnd="#id/priceLabel"
android:layout_marginTop="18dp"
android:fontFamily="#font/bold"
android:textColor="#color/colorPrimaryDarkV2"
android:textSize="18sp" />
<TextView
android:id="#+id/perPersonLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/priceValue"
android:layout_alignBaseline="#id/textViewThreeSixtyImages"
android:layout_alignEnd="#+id/priceValue"
android:fontFamily="#font/medium"
android:layout_marginBottom="24dp"
android:text="#string/perPersonLabel"
android:textColor="#color/colorPrimaryLightV2"
android:textSize="12sp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Then, here is the adapter giving the card view the values:
class ProductsAdapter(private val products: List<Product>) :
RecyclerView.Adapter<ProductsAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.view_layout_featuredproduct_row, parent, false)
view.layoutParams.height = (parent.measuredWidth - 40)/2 + 30
view.requestLayout()
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindProduct(products[position])
}
override fun getItemCount(): Int = products.size
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val image = view.findViewById<ShapeableImageView>(R.id.ivFeaturedProduct)
private val featuredProductTitle = view.findViewById<TextView>(R.id.textViewProductTitle)
private val category = view.findViewById<TextView>(R.id.textViewCategory)
private val featuredProductDuration = view.findViewById<TextView>(R.id.textViewDurationValue)
private val language = view.findViewById<TextView>(R.id.textViewLanguageValue)
private val averageRating = view.findViewById<TextView>(R.id.ratingValue)
private val ratingcount = view.findViewById<TextView>(R.id.ratingCount)
private val pricevalue = view.findViewById<TextView>(R.id.priceValue)
private val context = view.context
private val resources = view.resources
fun bindProduct(product: Product) {
with(product) {
val uri = this.header_image
Picasso.get().load(uri).
placeholder( R.drawable.progress_animation ).
transform(ColorFilterTransformation(ContextCompat.getColor(context, R.color.colorOverlay))).
into(image)
val categoryHelper = this.sku
if (categoryHelper[0].equals('S')){
category.text = resources.getString(R.string.skipTheLineTours)
category.setBackgroundResource(R.drawable.label_skipthelinetour)
category.setTextColor(resources.getColor(R.color.colorSkipTheLineTourTxt))
}
if (categoryHelper[0].equals('A')){
category.text = resources.getString(R.string.audioTours)
category.setBackgroundResource(R.drawable.label_audiotour)
category.setTextColor(resources.getColor(R.color.colorAudioTourTxt))
}
if(categoryHelper[0].equals('V')){
category.text = resources.getString(R.string.virtualTours)
category.setBackgroundResource(R.drawable.label_virtualtour)
category.setTextColor(resources.getColor(R.color.colorVirtualTourTxt))
}
featuredProductTitle.text = this.title
featuredProductDuration.text = this.duration+" minutes"
language.text = languages.size.toString()+" languages"
//category.text = this.sku
averageRating.text = this.average_rating
ratingcount.text = "("+this.rating_count.toString()+")"
pricevalue.text = this.retail_price.toString()+"€"
}
}
}
}
And last but not least, here is the code generating the recycler view:
class ExploreFragment : Fragment() {
private lateinit var viewProductsAdapter: ProductsAdapter
private val model: ProductsViewModel by activityViewModels()
private lateinit var featuredProducts: MutableList<Product>
private lateinit var viewManager : LinearLayoutManager
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_explore, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
loadFeaturedProducts()
}
private fun loadFeaturedProducts() {
if(!NetworkState().isNetworkAvailable(this#ExploreFragment.context!!.applicationContext)){
return;
}
featuredProducts = mutableListOf()
val recyclerView = rvExploreFragmentFeaturedProducts
viewProductsAdapter = ProductsAdapter(this.featuredProducts)
viewManager = LinearLayoutManager(this.context, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = viewManager
//recyclerView.setHasFixedSize(true)
recyclerView.adapter = viewProductsAdapter
Timber.i("Fragment: load featured products")
model.getProducts().observe(viewLifecycleOwner, { products->
if(products.status == Status.SUCCESS) {
this.featuredProducts.addAll(products.data!!)
viewProductsAdapter.notifyDataSetChanged()
}else {
Timber.i("Featured Products message: "+products.message)
Snackbar.make(view!!, "Cannot load featured products! Error:"+products.message, Snackbar.LENGTH_LONG).show()
}
})
}
}
Thank you for your answers - I figured out my mistake:
I couldn't see anything that was below the ImageView inside my CardView, even though it loaded correctly.
On ProductsListAdapter I forgot to remove an unnecessary calculation:
view.layoutParams.height = (parent.measuredWidth - 40)/2 + 30
view.requestLayout()
which was what caused the problem!
Instead of using the following code:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvExploreFragmentFeaturedProducts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
>
</androidx.recyclerview.widget.RecyclerView>
Please update it with
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvExploreFragmentFeaturedProducts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
/>
the Reason you are not getting data is tags! You are not closing tag of Recycler View instead you are creating a new scope to add more things in it like we do with Layouts.
So remove : </androidx.recyclerview.widget.RecyclerView> and add "/" to the closing tag of recycler view or just simply copy and paste my code above
I have a problem regarding livedata in custom views in android, I have a custom class with a text livedata that is two-way binded to the xml but the problem is that whenever the user writes any new value in the TextInputEditText the value of livedata is not changed.
class MaterialTextInput #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : MaterialCardView(context, attrs) {
val viewModel = MaterialTextInputViewModel()
init {
ViewMaterialTextInputBinding.inflate(
LayoutInflater.from(context), this, true
).apply {
viewModel = this#MaterialTextInput.viewModel
}
}
class MaterialTextInputViewModel : ViewModel() {
var text = MutableLiveData("")
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.app.utils.views.MaterialTextInput.MaterialTextInputViewModel" />
</data>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
app:strokeColor="#{viewModel.text.length() > 0 ? #color/color_4 : #color/white}"
app:strokeWidth="1dp">
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/email_address"
app:boxBackgroundColor="#color/white"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="1"
android:text="#={viewModel.text}" />
</com.google.android.material.textfield.TextInputLayout>
</com.google.android.material.card.MaterialCardView>
</layout>
I have met a strange problem, It didn't work when I set layout used for adapter item corners by shape resource file.
This is my shape resource file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:radius="8dp" />
</shape>
This is my adapter item layout
<?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>
<import type="android.view.View.OnClickListener" />
<import type="android.view.View" />
<import type="com.zhixin.wedeep.homepage.data.model.BriefComposition" />
<variable
name="clickListener"
type="OnClickListener" />
<variable
name="composition"
type="BriefComposition" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="108dp"
android:layout_height="150dp"
android:background="#drawable/homepage_shape_recommend_composition_background"
android:gravity="center"
android:onClick="#{clickListener}"
android:orientation="vertical">
<TextView
android:id="#+id/text_view_label_is_new"
android:layout_width="36dp"
android:layout_height="22dp"
android:text="#string/homepage_new"
android:textColor="#color/color_white"
android:textSize="#dimen/font_size_10"
android:visibility='#{composition.tag == "NEW" ? View.VISIBLE : View.INVISIBLE}'
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="新上" />
<ImageView
android:id="#+id/image_view_cover"
imageFromUrl="#{composition.cover}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:src="#drawable/gt3_new_bind_logo" />
<LinearLayout
android:id="#+id/linear_layout_text_area"
android:layout_width="match_parent"
android:layout_height="42dp"
android:orientation="vertical"
android:paddingStart="5dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="RtlSymmetry">
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="#{composition.title}"
android:textColor="#color/color_white"
android:textSize="#dimen/font_size_13"
tools:text="助眠脑波" />
<TextView
android:id="#+id/text_view_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:text="#{composition.duration}"
android:textColor="#color/color_white"
android:textSize="#dimen/font_size_10"
tools:text="5-30min" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
This is my RecylerView for display the above item layout
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_recommendation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
tools:itemCount="6"
tools:listitem="#layout/homepage_item_recommend_composition" />
This is my RecylerView Adapter
class RecommendCompositionsAdapter : ListAdapter<BriefComposition, RecommendCompositionsAdapter.ViewHolder>(BriefCompositionDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(HomepageItemRecommendCompositionBinding.inflate(
LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val briefComposition = getItem(position)
briefComposition?.let {
holder.apply {
itemView.tag = it
bind(createOnClickListener(it.id), it)
}
}
}
private fun createOnClickListener(id: String): View.OnClickListener {
return View.OnClickListener {
ARouter.getInstance().build(RouterConstant.PATH_AUDIO_PLAYER).withString(AudioPlayerActivity.KEY_ID, id).navigation()
}
}
class ViewHolder(private val binding: HomepageItemRecommendCompositionBinding)
: RecyclerView.ViewHolder(binding.root) {
fun bind(listener: View.OnClickListener, item: BriefComposition
) {
binding.apply {
clickListener = listener
composition = item
// from View
executePendingBindings()
}
}
}
}
Any ideas for this odd problem? Thank you in advance!
It looks like even if you are setting the background of your ConstraintLayout, it is overlapped by the ImageView and hence you are not getting the shape that your ConstraintLayout has. I would recommend using a CardView instead of the ConstraintLayout. Set the drawable as the background of your CardView and put everything inside of your CardView as you have done it for the ConstraintLayout.
I hope that helps!
I am trying to implement data binding in a Fragment but it's not working, the same code is working in Activity.
Fragment class
final FragmentHomeBinding fragmentHomeBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_home, container, false);
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
fragmentHomeBinding.setVariable(BR.homeViewModel, homeViewModel);
HomeEventHandler homeEventHandler = new HomeEventHandler(getActivity());
fragmentHomeBinding.setHandler(homeEventHandler);
EventHandlerClass
HomeEventHandler(Context mContext) {
this.mContext = mContext;
}
public void onButtonClick(View view) {
Log.e("DB", "onButtonClick: ");
switch (view.getId()){
case R.id.frag_home_ll_stock:
Toast.makeText(mContext, "clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(mContext, StockCheckActivity.class);
mContext.startActivity(intent);
}
}
and finally the xml file
<data>
<import type="android.view.View" />
<variable
name="fragment"
type="com.poc.ui.home.HomeFragment"/>
<variable
name="handler"
type="com.poc.ui.home.HomeEventHandler"/>
</data>
<LinearLayout
android:onClick="#{view->handler.onButtonClick(view)}"
android:id="#+id/frag_home_ll_stock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/grey_25"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<!--
-->
<TextView
android:id="#+id/frag_home_tv_op4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:clickable="false"
android:text="#string/w_stock_check"
android:textColor="#color/black"
android:textSize="18sp" />
<ImageView
android:id="#+id/frag_home_iv_op4"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clickable="false"
app:srcCompat="#drawable/ic_stock" />
</LinearLayout>
Remove the below line from your Fragment
View root = inflater.inflate(R.layout.fragment_home, container, false);
And If you need the view, you can pass with a parameter like below
android:onClick="#{(view) -> handler.onButtonClick(view)}"
Your LinearLayout should be like the following.
<LinearLayout
android:onClick="#{(view)->handler.onButtonClick(view)}"
android:id="#+id/frag_home_ll_stock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/grey_25"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<variable
name="HomeviewModel"
type="com.poc.ui.home.HomeviewModel"/> // exact path
you need to declare the viewmodel variable
android:onClick="#{(v) -> homeViewModel.buttonClicked(v, true)}"
if you are passing the parameter the function also should also contain same parameter
for e.g,
private void buttonClicked(View view, boolean value){
// your code
}
your method should look like this .
Try this one:
<ImageView
android:onClick="#{(view) -> handler.onButtonClick()}"
android:id="#+id/frag_home_iv_op3"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:srcCompat="#drawable/ic_report" />