I'm trying to vertically align my TextView to the centre using constraints within my MaterialCardView but it won't move at all for some reason. Does anyone know what's causing this problem to occur? Do constraints need to be used at all to achieve this? The affected component is the MaterialCardView with a white border. The word 'Information' + the drawable don't seem to be exactly in the vertical centre for some reason. It looks like there is a bit more space above the text view than below it for some strange reason (indicated by the orange line).
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myCardViewA"
app:cardUseCompatPadding="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/myConstraintLayoutA"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<ImageButton
android:id="#+id/myImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="#drawable/ic_chevron_down"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/myTextViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="#+id/myImageButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="#+id/myTextViewSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="#+id/myImageButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/myTextViewTitle"
app:layout_constraintHorizontal_bias="0.0"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Button"
android:textAllCaps="false"
android:padding="12dp"
app:layout_constraintTop_toBottomOf="#+id/myTextViewSubtitle"
app:layout_constraintBottom_toTopOf="#+id/myCardViewB"
app:layout_constraintStart_toEndOf="#+id/myImageButton"
app:layout_constraintHorizontal_bias="0.0" />
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myCardViewB"
android:clickable="false"
android:focusable="false"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#android:color/transparent"
app:contentPadding="12dp"
app:cardElevation="0dp"
app:layout_constraintTop_toBottomOf="#+id/myButton"
app:layout_constraintStart_toEndOf="#+id/myImageButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#+id/myTextViewDescription"
app:layout_constraintHorizontal_bias="0.0">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/myConstraintLayoutB"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/myTextViewinCardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.0"
android:text=""
style="#android:style/TextAppearance.Medium"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="#+id/myTextViewDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="#+id/myTextViewTitle"
app:layout_constraintTop_toBottomOf="#+id/myCardViewB"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
Kotlin
class MyFragment : androidx.fragment.app.Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.my_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
val v = view
val imageGetter = Html.ImageGetter { name ->
val resId = when (name) {
"door" -> { R.drawable.ic_door }
else -> { throw IllegalArgumentException("what is $name") }
}
ResourcesCompat.getDrawable(resources, resId, requireActivity().theme)?.apply {
setBounds(0, 0, intrinsicWidth, intrinsicHeight)
}
}
val info = getString(R.string.information)
val htmlTxt = "<img src=\"door\"/> $info
val myTxt = Html.fromHtml(htmlTxt, Html.FROM_HTML_MODE_COMPACT, imageGetter, null)
super.onActivityCreated(savedInstanceState)
}
}
Just remove app:layout_constraintHorizontal_bias="0.0"
The maximum is app:layout_constraintHorizontal_bias="1.0"
When you set "0.0" that mean you want it to the left and when it is "1.0" that mean it is to the right.
Related
add to cart errorI've used a recycler view inside another recycler view. While using test-driven development, I was trying to test the click functionality of add to cart button code as follows:
MenuDishAdapter- child recycler view
MenuAdapter- parent recycler view
class MenuAdapter(private val context: Context, val menuList:List<MenuData>, val menuActivity: MenuActivity):RecyclerView.Adapter<MenuAdapter.MenuViewHolder>() {
class MenuViewHolder(private val itemBinding:RvDishGroupBinding):RecyclerView.ViewHolder(itemBinding.root) {
val dishGroupBinding:RvDishGroupBinding = itemBinding
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MenuViewHolder = MenuViewHolder(
RvDishGroupBinding.inflate(LayoutInflater.from(parent.context), parent, false))
#SuppressLint("CutPasteId")
override fun onBindViewHolder(holder: MenuViewHolder, position: Int) {
val getPos= menuList[position]
holder.dishGroupBinding.dishCatgTypeMtv.text=getPos.categoryType
val adapter = MenuDishAdapter(context, menuList[position].categoryDish, menuActivity, )
holder.dishGroupBinding.dishLl.adapter= adapter
/*Logger.i("Menu list size ${menuList.size}")
Logger.i("Menu list $menuList")*/
if(position==menuList.size-1)
{
holder.dishGroupBinding.rvGroupSeparatorVw.visibility= View.GONE
}
}
override fun getItemCount(): Int = menuList.size
}
class MenuDishAdapter(
private val context: Context,
val menuList: List<DishData>,
val menuActivity: MenuActivity
) :
RecyclerView.Adapter<MenuDishAdapter.MenuDishViewHolder>() {
class MenuDishViewHolder(private val dishItem: RvDishItemBinding) :
RecyclerView.ViewHolder(dishItem.root) {
val dishItemBinding = dishItem
}
var isFavourite: Boolean = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MenuDishViewHolder =
MenuDishViewHolder(
RvDishItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
override fun onBindViewHolder(holder: MenuDishViewHolder, position: Int) {
val getPos= menuList[position]
Glide.with(context).load(getPos.dishImage).placeholder(R.drawable.img_dessert).into( holder.dishItemBinding.rvDishImgIv)
holder.dishItemBinding.rvDishNameMtv.text= getPos.dishName
if(getPos.dishDescription.isNullOrEmpty())
{
holder.dishItemBinding.rvDishDescriptionMtv.visibility=View.GONE
}
else
{
holder.dishItemBinding.rvDishDescriptionMtv.text= getPos.dishDescription
}
holder.dishItemBinding.rvDishPriceMtv.text= "$"+ getPos.dishPrice
if(!getPos.isVeg)
{
holder.dishItemBinding.rvDishTypeIv.backgroundTintList=
ContextCompat.getColorStateList(menuActivity, R.color.red)
}
holder.dishItemBinding.rvDishCustomizationMtv.text= context.getString(R.string.your_customisations_are)+" Radish, Mushroom, carrots, turnip, radish"
holder.dishItemBinding.rvDishFavMarkIb.setOnClickListener {
if(isFavourite)
{
holder.dishItemBinding.rvDishFavMarkIb.setBackgroundResource(R.drawable.ic_unfav)
Toast.makeText(context, "${getPos.dishName} removed from Favourite. ", Toast.LENGTH_SHORT).show()
notifyDataSetChanged()
isFavourite= false
}
else
{
holder.dishItemBinding.rvDishFavMarkIb.setBackgroundResource(R.drawable.ic_fav)
Toast.makeText(context, "${getPos.dishName} marked Favourite. ", Toast.LENGTH_SHORT).show()
notifyDataSetChanged()
isFavourite=true
}
}
holder.dishItemBinding.rvAddToCartBtn.setOnClickListener {
Utils.printShortToast(context, "${getPos.dishName} added to the cart")
}
holder.dishItemBinding.rvDishCustomizeBtn.setOnClickListener {
Utils.printShortToast(context, "${getPos.dishName} customised")
}
}
override fun getItemCount(): Int = menuList.size
}
XML for MenuDishAdapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="133dp"
android:layout_marginStart="6dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="6dp"
android:id="#+id/rv_dish_item_ll">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/detail_parent_cl"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/rv_dish_img_cv"
android:layout_width="109dp"
android:layout_height="104dp"
android:elevation="5dp"
app:cardCornerRadius="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/rv_dish_img_iv"
android:layout_width="109dp"
android:layout_height="104dp"
android:scaleType="fitXY"
tools:src="#drawable/img_fav_2" />
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/dish_details_ll"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="0dp"
android:orientation="vertical"
android:weightSum="5"
app:layout_constraintBottom_toBottomOf="#id/rv_dish_img_cv"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/rv_dish_img_cv"
app:layout_constraintTop_toTopOf="#id/rv_dish_img_cv">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/dish_name_cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/rv_dish_name_mtv"
style="#style/TextAppearance.MdcTypographyStyles.Body22"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:textColor="#color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/rv_dish_type_iv"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Masala Noodles" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/rv_dish_type_iv"
android:layout_width="21dp"
android:layout_height="18dp"
android:layout_gravity="end"
android:background="#drawable/ic_veg_dish"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/detail_middle_cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/text_ll"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/rv_dish_fav_mark_ib"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/rv_dish_description__mtv"
style="#style/TextAppearance.MdcTypographyStyles.Body12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:layout_marginEnd="2dp"
android:layout_marginStart="0dp"
android:textAlignment="textStart"
android:textColor="#color/black"
tools:text="#string/description" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/rv_dish_price_mtv"
style="#style/TextAppearance.MdcTypographyStyles.Body22"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAlignment="textStart"
tools:text="$10.5" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/rv_dish_fav_mark_ib"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:clickable="true"
android:elevation="5dp"
android:focusable="true"
android:paddingStart="10dp"
android:paddingTop="0dp"
android:paddingEnd="0dp"
android:paddingBottom="5dp"
android:background="#drawable/ic_unfav"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/buttons_cl"
android:layout_width="match_parent"
android:layout_height="23dp"
android:layout_marginTop="2dp"
android:paddingBottom="1dp"
android:paddingTop="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/rv_add_to_cart_btn"
style="#style/TextAppearance.MdcTypographyStyles.Button1"
android:layout_width="109dp"
android:layout_height="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="2dp"
android:background="#drawable/bg_button"
android:backgroundTint="#color/primaryColor"
android:drawableStart="#drawable/ic_button_cart"
android:drawablePadding="0dp"
android:focusable="true"
android:padding="2dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="#string/add_to_cart"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/rv_dish_customize_btn"
style="#style/TextAppearance.MdcTypographyStyles.Button1"
android:layout_width="109dp"
android:layout_height="0dp"
android:layout_marginStart="2dp"
android:layout_marginEnd="0dp"
android:background="#drawable/bg_button"
android:backgroundTint="#color/black"
android:focusable="true"
android:padding="2dp"
android:text="#string/customize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/rv_dish_customization_mtv"
style="#style/TextAppearance.MdcTypographyStyles.Body12"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="3dp"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/your_customisations_are"
android:textAlignment="textStart"
android:textColor="#color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/dish_details_ll"
app:layout_constraintStart_toStartOf="#id/rv_dish_img_cv"
app:layout_constraintTop_toBottomOf="#id/rv_dish_img_cv"
tools:text="Your customisations are - Onion, Tomato, Mushroom, cucumber, radish" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Now while testing the add to cart button the test case is as follows:
**Class name: MenuActivityTest
see code commented in testingMenuList() **
#RunWith(AndroidJUnit4::class)
#LargeTest
class MenuActivityTest {
#get:Rule
var rule = ActivityScenarioRule(MenuActivity::class.java)
//test to check the visibility of the menu screen layout on the device
#Test
fun checkScreenDisplay() {
onView(withId(R.id.menu_cl))
.check(matches(isDisplayed()))
}
#Test
fun testingMenuList() {
//testing whether the recycler view is displayed for not
onView(withId(R.id.menu_rv)).check(matches(isDisplayed()))
onView(allOf(withId(R.id.dish_ll), isDisplayed()))
//testing the scroll to position to 3rd position
onView(withId(R.id.menu_rv)).perform(
RecyclerViewActions
.scrollToPosition<RecyclerView.ViewHolder>(3)
)
//testing a particular item of the list
onView(allOf(withId(R.id.dish_catg_type_mtv), withText("Beverages")))
onView(allOf(withId(R.id.rv_dish_name_mtv), withText("Coffee")))
onView(allOf(withId(R.id.rv_dish_price_mtv), withText("0")))
onView(
allOf(
withId(R.id.rv_dish_description__mtv),
withText("Because ground coffee beans, coffee roasts, and brewing methods vary, so do coffee drinks. They come in so many different varieties and flavors, such as black coffee, espresso, latte, cappuccino, or mocha.")
)
)
/*onView(allOf(isDisplayed(), withId(R.id.rv_add_to_cart_btn)))
.perform(RecyclerViewActions.actionOnItemAtPosition<MenuDishAdapter.MenuDishViewHolder>(2, click()));
*/
/*val result = onView(
allOf(
withId(R.id.rv_add_to_cart_btn),
withText("Coffee")
)
).perform(
click()
)
Utils.printErrorLog("Result is: $result")*/
onView(allOf(withId(R.id.rv_add_to_cart_btn), isDescendantOfA(allOf(withId(R.id.buttons_cl))))).check(matches(isFocusable()))
*/
/* onData(allOf(withId(R.id.rv_add_to_cart_btn)))
.inAdapterView(allOf(withId(R.id.rv_dish_item_ll)))
.atPosition(1)
.perform(click())*/
}
}
Each and every time in running the testingMenuList I'm getting the error(screenshot attached).
What is the correct method to check the add to cart button click functionality?
The flow is as: MenuActivity has a recycler view menu_rv and this menu_rv contains another recycler view name dish_ll. Inside dish_ll, rv_add_to_cart_btn is the button that is being tested using the TDD approach.
I'm using multiple TextInputLayout in each element in a Recycling View.
I noticed that navigating to the fragment containing this list is slow and scrolling for the first few seconds is also slow. As soon as I remove the TextInputLayout the performance drastically improves.
Is there a way to render the TextInputLayout in a recycling view with a good performance?
I mostly want to use this layout for its animations and design.
This is my layout for a individual item in recycling view:
<?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="200dp"
android:layout_margin="16dp"
android:background="#FFFFFF"
android:elevation="8dp">
<ImageButton
android:id="#+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_baseline_add_24" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="Bench Press"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
style="#style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="28dp"
android:text="Remove Exercise"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/linearLayout" />
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
android:baselineAligned="false">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField1"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:hint="Reps">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField2"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:hint="Sets">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField3"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:hint="Rest">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment code:
class EditRoutineFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_edit_routine, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = EditRoutineListAdapter()
requireView().rv_list.apply {
this.adapter = adapter
layoutManager = LinearLayoutManager(context)
setHasFixedSize(true)
}
}
}
Recycling View Adapter
class EditRoutineListAdapter: RecyclerView.Adapter<EditRoutineListAdapter.ViewHolder>() {
class ViewHolder(itemView: ViewGroup): RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.rv_edit_routine_list_item, parent, false) as ViewGroup
return ViewHolder(view)
}
override fun getItemCount() = 16
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
}
}
You can leftout the ImageButton and use the built in option like:
app:endIconMode="custom"
app:endIconDrawable="#drawable/ic_check_circle_24dp"
app:endIconContentDescription="#string/content_description_end_icon"
Check also RecyclerView on Bind method taking too long(that is, onBindViewHolder(VH, int)) should be very simple, and take much less than one millisecond for all but the most complex items.
Currently I am finishing the last details of my project and I am trying to keep a certain part inside a nested scrollview to stay on top of the screen and let only the recyclerview scroll.
This is the code I have right now:
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/marktplaats_refresh"
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">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:tint="#9F000000"
app:layout_constraintCircleRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/offer_bg"/>
<Button
android:id="#+id/verkoopEenProduct"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:background="#null"
android:text="Verkoop een product"
android:textColor="#color/white"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="#+id/button5"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:background="#drawable/light_contact_buttons"
android:hint="Zoek in marktplaats"
android:textAlignment="center"
android:gravity="center_vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView33"/>
<TextView
android:id="#+id/textView32"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="Marktplaats"
android:textColor="#color/white"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/verkoopEenProduct"/>
<TextView
android:id="#+id/textView33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="Hier vind u alles wat u nodig\nhebt voor uw praktijk"
android:textColor="#color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView32"/>
<TextView
android:id="#+id/textView34"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="Alle producten"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView14"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/marktplaats_recyclerview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView34"/>
<Button
android:id="#+id/button11"
android:translationX="-20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#null"
android:rotation="180"
android:text="➜"
android:textColor="#color/white"
android:textSize="36sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
And this is my kotlin
class MarktplaatsOverview : ApplicationFragment(){
var products: Array<MarketModel> = arrayOf()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.fragment_marktplaats, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
marktplaats_refresh.setOnRefreshListener {
refreshData()
marktplaats_refresh.isRefreshing = false
}
button11.setOnClickListener {
navController.navigate(R.id.action_marktplaatsOverview_to_more)
}
button5.requestFocus()
refreshData()
verkoopEenProduct.setOnClickListener {
navController.navigate(R.id.action_marktplaatsOverview_to_marktplaatsDetail)
}
}
private fun refreshData() {
if (DataStorage.market.isNotEmpty()) {
setupRecyclerView()
} else {
SharedInstance.api.getAllMarketItems {
if (isAdded) {
setupRecyclerView()
}
}
}
}
private fun setupRecyclerView(){
SharedInstance.api.getAllMarketItems {
products = DataStorage.market
val xLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
xLayoutManager.stackFromEnd = true
marktplaats_recyclerview.layoutManager = xLayoutManager
marktplaats_recyclerview.adapter = MarktplaatsAdapter(products)
}
}
}
Does anyone have a solution for this awkward problem? I've been trying to do some restructuring of the swiperefreshlayout, scrollviews and constraints but no succes so far.
I also can't find anything on the internet where someone wants the same as me...
As per your question description, I am assuming that you face an issue that recycler view scroll or take focus automatically while you open screen and you need to stick layout at the top so pass this field on your parent layout.
android:descendantFocusability="blocksDescendants"
or replace your SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/marktplaats_refresh"
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:descendantFocusability="blocksDescendants"
android:layout_height="match_parent">
I hope it helps you.
I've created a custom view called SectionRowView which extends a ConstraintLayout which is as simple as:
class SectionRowView : ConstraintLayout {
constructor(context: Context?) : super(context) {
inflate(context, R.layout.section_row_view, this)
}
}
SectionRowView inflates it's view from sectionrowview.xml:
<merge 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/container">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:id="#+id/topBorder" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
android:background="#979797"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="32dp"
android:id="#+id/checkBox" android:layout_marginTop="15dp"
app:layout_constraintTop_toBottomOf="#+id/topBorder" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="30dp"
android:text="test test test test test test"/>
</merge>
In a fragment I then add this custom view to a TableRow inside a TableLayout:
class CustomizeQuizFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_customize_quiz, container, false)
val tableView = view.findViewById<TableLayout>(R.id.tableView)
setupTable(tableView)
return view
}
private fun setupTable(tableView: TableLayout) {
val layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
val tableRow = TableRow(context)
tableRow.layoutParams = layoutParams
val sectionView = SectionRowView(context)
sectionView.layoutParams = layoutParams
tableRow.addView(sectionView)
tableView.addView(tableRow)
}
}
The xml layout for my fragment looks like this:
<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/container">
<TextView
android:text="Test"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/title" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="70dp" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="32sp" android:gravity="center_horizontal|top" android:layout_marginStart="30dp"
android:layout_marginEnd="30dp" android:textColor="#3C6FF3"/>
<TableLayout
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_marginTop="34dp"
app:layout_constraintTop_toBottomOf="#+id/title" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" android:id="#+id/tableView" android:background="#00EC0909"/>
<Button
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/startButton"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent" android:background="#drawable/customstartbutton"
android:textColor="#EFFBFD" android:textAllCaps="false" android:textSize="26sp"
android:layout_marginBottom="30dp" app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
When I run this, I can see in the layout inspector that the SectionRowView's width is not extending to match_parent like it's told to. It's parent element the TableRow has a fullscreen width like its supposed to:
Using SectionRowView inside of a LinearLayout works just fine with the width extending to full screen. It seems to only have trouble inside a TableRow.
What am I doing wrong?
I have one page called products. When page is loaded it shows productsfragment. This fragment has one RecyclerView which doesn't have any problem. On selecting a product a new fragment opens up and shows the list of product prices fragment. This fragment has one RecyclerView and the scrolling here doesn't works.
I tried gridview and cardview but they too are not scrolling. I tried gridview in scroll view or nested scroll view, they are also not scrolling.
here is my fragment with RecyclerView which is not scrolling
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/sorderfragment_step1_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activities.OrderSelect.Fragments.ProductSingleOrder.SOrderFragment_Step1">
<android.support.v7.widget.RecyclerView
android:id="#+id/gvProductPrices"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
and its my RecyclerView item view
<?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:layout_width="200dp"
android:layout_height="200dp"
android:gravity="center"
android:maxHeight="200dp"
android:minHeight="200dp"
android:background="#layout/border2"
android:padding="0dp"
android:orientation="vertical">
<TextView
android:id="#+id/txtPriceName"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="Kucuk Boy Whopper"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="#+id/constraintLayout4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintLayout4"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="0dp"
android:background="#000000"
app:layout_constraintBottom_toTopOf="#+id/txtPrice"
app:layout_constraintEnd_toEndOf="parent">
</android.support.constraint.ConstraintLayout>
<TextView
android:id="#+id/txtPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:gravity="center"
android:text="14.99"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</LinearLayout>
and my adapter
class PriceAdapter(val priceList : List<ProductPrice>,
val context: Context) : RecyclerView.Adapter<ViewHolder>() {
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.gv_product_prices, p0, false))
}
override fun getItemCount(): Int {
return priceList.size
}
override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
val price = priceList[p1]
p0.txtPriceName.text = price.getDescription()
p0.txtPriceName.isAllCaps = true
p0.txtPrice.text = BaseHelper.getNumericStr(price.getPrice())
}
}
class ViewHolder (view: View) : RecyclerView.ViewHolder(view) {
val txtPriceName = view.txtPriceName!!
val txtPrice = view.txtPrice!!
}
and my fragment code
class SOrderFragment_Step1 : Fragment() {
private var _priceRepository = ProductPriceRepository(OrderRepository.orderSelect!!)
private var priceAdapter: PriceAdapter? = null
private var prices: List<ProductPrice>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_sorder_step1, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
configurePrices()
}
private fun configurePrices() {
prices = _priceRepository.getPriceByProductId(OrderRepository.currentProduct!!.getId())
gvProductPrices.layoutManager = GridLayoutManager(OrderRepository.orderSelect!!, 2)
gvProductPrices.adapter = PriceAdapter(prices!!, this, OrderRepository.orderSelect!!)
}
fun priceSelect(price: ProductPrice) {
Toast.makeText(OrderRepository.orderSelect!!, price.getDescription(), Toast.LENGTH_LONG).show()
}
}
and also fragment change like this
val manager = this.fragmentManager!!.beginTransaction()
manager.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
manager.replace(R.id.fragmentProductSteps, SOrderFragment_Step1(), "detailFragment").commit()
and fragment base activity xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/order_select_layout"
tools:context=".OrderSelect">
<GridView
android:id="#+id/gvProductGroups"
android:layout_width="165dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/linearLayout" />
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="225dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="7">
<include
layout="#layout/activity_advertise_partition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/orderProductLayout"
android:layout_width="0dp"
android:layout_height="83dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="#layout/gv_order_products_border"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btnCancelCurrentOrder2"
app:layout_constraintStart_toEndOf="#+id/gvProductGroups">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:id="#+id/paymentView"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:layout_weight="1">
<TextView
android:id="#+id/txtTotalL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TOPLAM :"
android:textColor="#bc3030"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtPriceL"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="-1dp"
android:layout_weight="1"
android:gravity="left|center"
android:text="₺ 0.00"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imgOrderButton"
app:layout_constraintStart_toEndOf="#+id/txtTotalL"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="#+id/imgOrderButton"
android:layout_width="175dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="#15912e"
android:padding="15sp"
android:text="Sepeti Goster"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
<fragment
android:id="#+id/fragmentProductSteps"
android:name="com.example.alknakralar.kios.Helpers.BlankFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/orderProductLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/gvProductGroups"
app:layout_constraintTop_toBottomOf="#+id/linearLayout" />
<Button
android:id="#+id/btnCancelCurrentOrder2"
android:layout_width="125dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:background="#ff0000"
android:text="SEPETI BOSALT"
android:textColor="#FFFFFF"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imgBackFromProducts"
app:layout_constraintTop_toBottomOf="#+id/fragmentProductSteps" />
<ImageView
android:id="#+id/imgBackFromProducts"
android:layout_width="70dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fragmentProductSteps"
app:srcCompat="#drawable/back" />
</android.support.constraint.ConstraintLayout>
How can i fix this issue ?
Sugession: Why are you using grid view and setting adapter to it where you have another approach and commonly used approach.
Which is to use recycler view and set its layout manager as GridLayout manager
Below single line will make your job done
recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));