Mayank Gupta
Mayank Gupta

Reputation: 59

GridView Problem with row Height and Scrolling - Android Kotlin

I have been working on an Android Project(Kotlin) and have been facing some issues.

The project overview and issues:

Issue 1 : I am developing an application with a navigation drawer and fragments. In one of my fragments, I am using a gridview, which has cardview elements(Refer to the first image). I have provided the code just below the image. (In ProductFragment.kt only refer to the category_list and the corresponding code)

fragment_product.xml

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
tools:context=".Fragments.ProductFragment">

<GridView
    android:id="@+id/product_gridview"
    android:columnWidth="100dp"
    android:verticalSpacing="15dp"
    tools:listitem="@layout/gridview_card_item"
    android:horizontalSpacing="15dp"
    android:numColumns="auto_fit"
    android:layout_margin="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</LinearLayout>

gridview_card_item.xml

<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
app:cardPreventCornerOverlap="true"
android:layout_margin="10dp"
app:cardElevation="5dp">

<RelativeLayout
    android:layout_width="match_parent"
    android:padding="10dp"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/gridview_card_item_logo"
        android:layout_width="90dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="5dp"
        android:src="@drawable/paypal"
        android:layout_height="90dp"/>
    
    <TextView
        android:id="@+id/gridview_card_item_name"
        android:text="Learning and Educational Toys"
        android:breakStrategy="simple"
        android:ellipsize="none"
        android:textAlignment="center"
        android:textStyle="bold"
        android:layout_below="@+id/gridview_card_item_logo"
        android:layout_centerHorizontal="true"
        android:textColor="#000000"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>

Product_Fragment.kt

class ProductFragment : Fragment() {
// TODO: Rename and change types of parameters
private var name: String? = null

val category_list = arrayListOf<GridViewCardItemModel>(
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "Musical Toys"
    ),
    GridViewCardItemModel(
        R.drawable.ethereum,
        "RC Toys"
    ),
    GridViewCardItemModel(
        R.drawable.paypal,
        "Learning & Educational Toys"
    ),
    GridViewCardItemModel(
        R.drawable.xrp,
        "Play Gyms & Play Mats"
    ),
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "Blocks & Construction Sets"
    ),
    GridViewCardItemModel(
        R.drawable.ethereum,
        "Baby Rattles and Teethers"
    ),
    GridViewCardItemModel(
        R.drawable.paypal,
        "Toy Cars Trains & Vehicles"
    ),
    GridViewCardItemModel(
        R.drawable.xrp,
        "Push & Pull Along Toys"
    ),
    GridViewCardItemModel(
        R.drawable.paypal,
        "Push & Pull Along Toys"
    ),
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "Push & Pull Along Toys"
    )
)
val age_list = arrayListOf<GridViewCardItemModel>(
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "0 to 6 months"
    ),
    GridViewCardItemModel(
        R.drawable.ethereum,
        "6 to 12 months"
    ),
    GridViewCardItemModel(
        R.drawable.paypal,
        "12 to 24 months"
    ),
    GridViewCardItemModel(
        R.drawable.xrp,
        "2 to 4 years"
    ),
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "5 to 7 years"
    ),
    GridViewCardItemModel(
        R.drawable.ethereum,
        "8 to 10 years"
    ),
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "11 to 13 years"
    ),
    GridViewCardItemModel(
        R.drawable.xrp,
        "14 to 15years"
    ),
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "Above 15 years"
    )
)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        name = it.getString("name")
    }
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.fragment_product, container, false)
    return view
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    product_gridview.apply {
        if(name=="Category"){
            adapter = GridViewAdapter(
                context,
                category_list
            )
        }else{
            adapter = GridViewAdapter(
                context,
                age_list
            )
        }
    }
}

companion object {
    fun newInstance(name: String) : ProductFragment {
        val args = Bundle()
        args.putString("name",name)
        val fragment = ProductFragment()
        fragment.arguments = args
        return fragment
    }
}
}

GridViewAdapter.kt

 class GridViewAdapter(var context: Context,var ArrayList: 
 ArrayList<GridViewCardItemModel>):BaseAdapter(){
 override fun getView(position: Int, view: View?, parent: ViewGroup?): View {
    var view = View.inflate(context,R.layout.gridview_card_item,null)
    var icon = view.gridview_card_item_logo
    var name = view.gridview_card_item_name

    var listItem = arrayList.get(position)

    icon.setImageResource(listItem.icons)
    name.text = listItem.name
    return view
}

override fun getItem(position: Int): Any  = arrayList.get(position)

override fun getItemId(position: Int): Long = position.toLong()

override fun getCount(): Int = arrayList.size
}

Issue 2: Refer to the second image for this. This is my home fragment. I have implemented a similar gridview under categories. Now I want the whole page to scroll instead of only the gridview section. I have tried putting the whole home_fragment layout under scrollview, but it did not help.

Fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Fragments.HomeFragment">

<com.denzcoskun.imageslider.ImageSlider
    android:id="@+id/image_slider"
    android:layout_height="200dp"
    android:layout_width="match_parent"
    android:padding="20dp"
    app:iss_selected_dot="@drawable/default_selected_dot"
    app:iss_unselected_dot="@drawable/default_unselected_dot"
    app:iss_error_image="@drawable/error"
    app:iss_auto_cycle="true"
    app:iss_period="1000"
    app:iss_delay="0" />

<TextView
    android:id="@+id/most_selling"
    android:text="Most Selling"
    android:layout_below="@+id/image_slider"
    android:layout_margin="15dp"
    android:textColor="#000000"
    android:textSize="30sp"
    android:textStyle="bold"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/homeRecyclerView"
    android:layout_below="@+id/most_selling"
    android:orientation="horizontal"
    tools:listitem="@layout/cardview_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"/>

<TextView
    android:id="@+id/categories"
    android:text="Categories"
    android:layout_below="@+id/homeRecyclerView"
    android:layout_margin="15dp"
    android:textColor="#000000"
    android:textSize="30sp"
    android:textStyle="bold"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<GridView
    android:id="@+id/home_gridview"
    android:columnWidth="100dp"
    android:verticalSpacing="15dp"
    android:horizontalSpacing="15dp"
    android:numColumns="auto_fit"
    android:layout_below="@id/categories"
    android:layout_margin="20dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
</RelativeLayout>

HomeFragment.kt

class HomeFragment : Fragment() {

val view_image_list = arrayListOf<Int>(
    R.drawable.image_slide,
    R.drawable.image_slide_2,
    R.drawable.image_slide_3,
    R.drawable.image_slide_4,
    R.drawable.image_slide_5
)
val view_title_list = arrayListOf<String>("Bali","Thailand","Malaysia","America","France")
val view_price_list = arrayListOf<String>("42,5000","34,000","56,000","78,000","67,000")
val gridviewlist = arrayListOf<GridViewCardItemModel>(
    GridViewCardItemModel(
        R.drawable.bitcoin,
        "Bitcoin"
    ),
    GridViewCardItemModel(
        R.drawable.ethereum,
        "Ethereum"
    ),
    GridViewCardItemModel(
        R.drawable.paypal,
        "Paypal"
    ),
    GridViewCardItemModel(R.drawable.xrp, "XRP")
)


override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_home, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val imageList = ArrayList<SlideModel>()
    imageList.add(SlideModel(R.drawable.image_slide))
    imageList.add(SlideModel(R.drawable.image_slide_2))
    imageList.add(SlideModel(R.drawable.image_slide_3))
    imageList.add(SlideModel(R.drawable.image_slide_4))
    imageList.add(SlideModel(R.drawable.image_slide_5))

    val imageSlider = view.findViewById<ImageSlider>(R.id.image_slider)
    imageSlider.setImageList(imageList,ScaleTypes.FIT)

    homeRecyclerView.apply{
        layoutManager = LinearLayoutManager(activity,LinearLayoutManager.HORIZONTAL,false)
        adapter = HomeRecyclerViewAdapter(
            view_image_list,
            view_title_list,
            view_price_list
        )
    }

    home_gridview.apply {
        adapter = GridViewAdapter(
            context,
            gridviewlist
        )
    }
}
}

Upvotes: 0

Views: 1137

Answers (1)

Faraz Ahmed
Faraz Ahmed

Reputation: 149

Issue 1: Use match parent in both height and width in item.xml

Issue 2: layout_height="wrap_content" can't be used in GridView in fact it can't be used in subclasses of AdapterView (e.g. ListView and GridView). You'll have to calculate each item's height dynamically and then set the gridview height accordingly. Instead of doing this much work, just use a recyclerview with a grid layout and set its height as wrap_content

and also disable nested scrolling in this recyclerview

recycler.setNestedScrollingEnabled(false);

Upvotes: 1

Related Questions