I have an issue with animations. I have defined two simple layouts:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/root"
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">
<ImageView
android:id="#+id/player1"
android:layout_width="50dp"
android:layout_height="77dp"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:src="#drawable/two_hearts"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
looking like this:
and
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/root"
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">
<ImageView
android:id="#+id/player1"
android:layout_width="50dp"
android:layout_height="77dp"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:src="#drawable/two_hearts"
android:translationY="-60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
with looks:
The difference between them is android:translationY="-60dp".
I switch between them in the GameFragment.kt:
class GameFragment: Fragment() {
private lateinit var root: ConstraintLayout
private var expanded = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
root = inflater.inflate(R.layout.fragment_game_hidden, container, false) as ConstraintLayout
root.setOnClickListener {
show()
}
return root
}
private fun show() {
if (expanded) {
updateConstraints(R.layout.fragment_game_hidden)
} else {
updateConstraints(R.layout.fragment_game_shown)
}
expanded = !expanded
}
private fun updateConstraints(#LayoutRes id: Int) {
val newConstraintSet = ConstraintSet()
newConstraintSet.clone(context, id)
val transition = ChangeBounds()
transition.interpolator = AccelerateDecelerateInterpolator()
transition.duration = 1000
newConstraintSet.applyTo(root)
TransitionManager.beginDelayedTransition(root, transition)
}
}
My problem is, the animation is not played at all, the card on the layout just jumps to target location without any transition. Why? I feel like I'm missing something obvious here...
Remove android:translationY="-60dp" in : fragment_game_hidden.xml . Just use margin directly.
Try change to code below:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/root"
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">
<ImageView
android:id="#+id/player1"
android:layout_width="50dp"
android:layout_height="77dp"
android:layout_marginStart="32dp"
android:src="#drawable/two_hearts"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
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 trying make a custom dialog, and I want to draw some shapes on it's layout. The shapes are drawn fine when I put in an activity, but disappears when I use in the a dialog fragment.
The example below has a button that shows MyDialog() which inflates view_ticket, which contains CanvasView. However, the red dot is not drawn! :(
Below is a screenshot. Notice the red dot in the background, but not in the dialog!
SCREENSHOT
CanvasView.kt
class CanvasView(context: Context, attributeSet: AttributeSet) : LinearLayout(context, attributeSet) {
init {
setWillNotDraw(false)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if(canvas == null) return
val p = Paint()
p.color = Color.RED
canvas.drawCircle(400f, 200f, 50f, p)
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
MyDialog().show(supportFragmentManager,null)
}
}
}
class MyDialog : DialogFragment(){
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return View.inflate(context,R.layout.dialog_ticket,container)
}
}
dialog_ticket.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"
android:layout_width="300dp"
android:background="#color/white"
android:layout_height="400dp">
<TextView
android:layout_width="300dp"
android:layout_height="400dp"
android:text="hello"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.mikkelthygesen.canvassample.CanvasView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DRAW"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.mikkelthygesen.canvassample.CanvasView
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_toBottomOf="#+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is my recycler view items xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recyclerItem"
app:cardElevation="10dp"
app:cardUseCompatPadding="false"
app:cardCornerRadius="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/recyclerItemImageView"
android:padding="8dp"
android:src="#mipmap/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView
android:id="#+id/recyclerItemTextView"
android:layout_marginStart="4dp"
android:textSize="18sp"
android:textColor="#color/black"
android:text="item"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</androidx.cardview.widget.CardView>
And preview show me like this:
Preview
But emulator result this:
Emulator result
So items in recycler view does not match parent width on emulator. Other xml's there are:
<?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=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainerView"
android:layout_margin="16dp"
android:name="com.example.databinding_practice.ListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/activityTextView"/>
<TextView
android:id="#+id/activityTextView"
android:layout_margin="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="#color/black"
android:textSize="20sp" />
</RelativeLayout>
And 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=".ListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Adapter class and ListFragment like this:
RecyclerAdapter.kt:
class RecyclerAdapter(var recyclerItems: ArrayList<RecyclerItemModel>) : RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>() {
class RecyclerViewHolder(val binding: RecyclerItemBinding) : RecyclerView.ViewHolder(binding.root) {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
val binding = RecyclerItemBinding.inflate(LayoutInflater.from(parent.context))
return RecyclerViewHolder(binding)
}
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
holder.binding.recyclerItemTextView.text = recyclerItems[position].text
recyclerItems[position].imageMipmapSource?.let { holder.binding.recyclerItemImageView.setImageResource(it) }
}
override fun getItemCount(): Int {
return recyclerItems.size
}
}
ListFragment.kt:
class ListFragment : Fragment() {
private var itemList : ArrayList<RecyclerItemModel> = arrayListOf()
private var recyclerAdapter: RecyclerAdapter = RecyclerAdapter(arrayListOf())
private lateinit var fragmentListBinding: FragmentListBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
fragmentListBinding = FragmentListBinding.inflate(layoutInflater)
return fragmentListBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
for (i in 0..3){
itemList.add(RecyclerItemModel(R.mipmap.ic_launcher,"Item $i"))
}
fragmentListBinding.recyclerView.layoutManager = LinearLayoutManager(context)
fragmentListBinding.recyclerView.adapter = recyclerAdapter
recyclerAdapter.recyclerItems = itemList
recyclerAdapter.notifyDataSetChanged()
}
Where am I doing wrong? If I replace match parent to fixed size like 200 dp - 300dp , thats working correctly but match parent does not. And why preview and emulator does not match ? Thank you.
In the fragment you should change layout_width and layout_height to "0dp" in your RecyclerView.
<?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=".ListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
I was able to create a bottom sheet card view. I am trying convert what I haveto a top sheet card view(when user clicks button, card view should appear from the top, not bottom). Any assistance is appreciated.
SheetBehaviorActivity.kt
class SheetBehaviourActivity : AppCompatActivity() {
lateinit var sheetBehavior: BottomSheetBehavior<*>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btn: Button = this.findViewById(R.id.testing_bottom_sheet_btn)
btn.setOnClickListener {
if (sheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
btn.text = "Close sheet"
} else {
sheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
btn.text = "Expand sheet"
}
}
val sheetContainer = findViewById<CardView>(R.id.bottom_sheet_container)
sheetBehavior = BottomSheetBehavior.from(sheetContainer)
sheetBehavior.isHideable = true
sheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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=".activities.SheetBehaviourActivity">
<Button
android:id="#+id/testing_bottom_sheet_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Expand Sheet" />
<android.support.v7.widget.CardView
android:id="#+id/bottom_sheet_container"
android:layout_width="match_parent"
app:cardCornerRadius="20dp"
app:cardBackgroundColor="#android:color/holo_blue_light"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:layout_height="300dp"/>
</android.support.design.widget.CoordinatorLayout>
This is TopSheetBehavior implementation topSheetLayout work fine in my case
Here is how you do it :
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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=".activities.SheetBehaviourActivity">
<Button
android:id="#+id/testing_bottom_sheet_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Expand Sheet" />
<android.support.v7.widget.CardView
android:id="#+id/bottom_sheet_container"
android:layout_width="match_parent"
app:cardCornerRadius="20dp"
app:cardBackgroundColor="#android:color/holo_blue_light"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior"/>
</android.support.design.widget.CoordinatorLayout>
This TopSheetBehavior is just replacing the behavior parameter
I am trying to make a bottom sheet with a recyclerview with cards. I was able to put the the cards within the bottom sheet but I am having problems with the recyclerview. As shown in the photo, it creates multiple bottom sheets with the cards within them. I have tried to fix this but so far have no luck. How can I make it so that the bottom sheet contains the cards with a recyclerview? I believe the problem is the Recyclerview in activity_main but don't know where to place it.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (supportActionBar != null)
supportActionBar?.hide()
val modelList = readFromAsset()
val adapter = CustomAdapter(modelList, this)
rcv.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) as RecyclerView.LayoutManager?
rcv.adapter = adapter;
configureBackdrop()
}
private var mBottomSheetBehavior: BottomSheetBehavior<View?>? = null
private fun configureBackdrop() {
// Get the fragment reference
val fragment = supportFragmentManager.findFragmentById(R.id.filter_fragment)
fragment?.let {
// Get the BottomSheetBehavior from the fragment view
BottomSheetBehavior.from(it.view)?.let { bsb ->
mBottomSheetBehavior = bsb
}
}
}
private fun readFromAsset(): List<Model> {
val modeList = mutableListOf<Model>()
val bufferReader = application.assets.open("android_version.json").bufferedReader()
val json_string = bufferReader.use {
it.readText()
}
val jsonArray = JSONArray(json_string);
for (i in 0..jsonArray.length() - 1) {
val jsonObject: JSONObject = jsonArray.getJSONObject(i)
val model = Model(jsonObject.getString("name"), jsonObject.getString("version"))
modeList.add(model)
}
return modeList
}
}
CustomAdapter.kt
class CustomAdapter(val modelList: List<Model>, val context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).bind(modelList.get(position));
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return ViewHolder(layoutInflater.inflate(R.layout.backdrop_fragment, parent, false))
}
override fun getItemCount(): Int {
return modelList.size;
}
lateinit var mClickListener: ClickListener
fun setOnItemClickListener(aClickListener: ClickListener) {
mClickListener = aClickListener
}
interface ClickListener {
fun onClick(pos: Int, aView: View)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
init {
itemView.setOnClickListener(this)
}
override fun onClick(p0: View?) {
mClickListener.onClick(adapterPosition, itemView)
}
fun bind(model: Model): Unit {
itemView.txt.text = model.name
itemView.sub_txt.text = model.version
val id = context.resources.getIdentifier(model.name.toLowerCase(), "drawable", context.packageName)
itemView.img.setBackgroundResource(id)
}
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/textView"
android:text="#string/main_activity_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:id="#+id/rcv"/>
<fragment
app:behavior_hideable="false"
app:behavior_peekHeight="100dp"
android:layout_marginTop="?attr/actionBarSize"
app:behavior_skipCollapsed="false"
android:id="#+id/filter_fragment"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:name="behavior.sheet.bottom.BackdropFragment" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
backdrop_fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backdrop_fragment_background"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/backdrop_content" />
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="75dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
card_view:cardCornerRadius="30dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="false"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
card_view:contentPadding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="Title"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/img"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="#+id/txt"
android:contentDescription="#string/app_name" />
<TextView
android:id="#+id/sub_txt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="#+id/img"
android:autoSizeMaxTextSize="8sp"
android:autoSizeMinTextSize="6sp"
android:autoSizeStepGranularity="2sp"
android:autoSizeTextType="uniform"
android:text="Title" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
Please set the Bottom sheet Linear Layout to wrap-content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/backdrop_fragment_background"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/backdrop_content" />
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="75dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
card_view:cardCornerRadius="30dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="false"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
card_view:contentPadding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="Title"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/img"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="#+id/txt"
android:contentDescription="#string/app_name" />
<TextView
android:id="#+id/sub_txt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="#+id/img"
android:autoSizeMaxTextSize="8sp"
android:autoSizeMinTextSize="6sp"
android:autoSizeStepGranularity="2sp"
android:autoSizeTextType="uniform"
android:text="Title" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
You have the RecyclerView in the activity_main layout file instead of inside the Fragment layout file.
Here is what you should do, create a class that inherits BottomSheetDialogFragment(). See below.
Add dependency implementation 'com.google.android.material:material:1.2.0-alpha04' inside the app/build.gradle.
Create your bottom sheet class
class BottomSheetExampleDialogFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) : View? =
inflater.inflate(R.layout.bottom_sheet_example_dialog_fragment, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Handle RecyclerView here
}
}
Bottom sheet layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Then in your MainActivity you can show the bottom sheet by using
val bottomSheetFragment = BottomSheetExampleDialogFragment()
bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.getTag())