GridView 行高和滚动问题 - Android Kotlin
GridView Problem with row Height and Scrolling - Android Kotlin
我一直在从事 Android 项目 (Kotlin),但遇到了一些问题。
项目概况及问题:
问题 1:
我正在开发一个带有导航抽屉和片段的应用程序。在我的一个片段中,我使用了一个 gridview,它有 cardview 元素(参考第一张图片)。我在图片下方提供了代码。 (在ProductFragment.kt中仅参考category_list和对应的代码)
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
}
问题 2:请参考第二张图片。这是我家的片段。我在类别下实现了类似的gridview。现在我希望整个页面滚动,而不仅仅是 gridview 部分。我试过将整个 home_fragment 布局放在滚动视图下,但没有帮助。
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
)
}
}
}
问题 1:
在 item.xml
的高度和宽度中使用匹配父项
问题二:
layout_height="wrap_content" 不能在 GridView 中使用,事实上它不能在 AdapterView 的子类中使用(例如 ListView 和 GridView)。您必须动态计算每个项目的高度,然后相应地设置 gridview 高度。
不用做这么多工作,只需使用带有网格布局的 recyclerview 并将其高度设置为 wrap_content
并在此 recyclerview 中禁用嵌套滚动
recycler.setNestedScrollingEnabled(false);
我一直在从事 Android 项目 (Kotlin),但遇到了一些问题。
项目概况及问题:
问题 1: 我正在开发一个带有导航抽屉和片段的应用程序。在我的一个片段中,我使用了一个 gridview,它有 cardview 元素(参考第一张图片)。我在图片下方提供了代码。 (在ProductFragment.kt中仅参考category_list和对应的代码)
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
}
问题 2:请参考第二张图片。这是我家的片段。我在类别下实现了类似的gridview。现在我希望整个页面滚动,而不仅仅是 gridview 部分。我试过将整个 home_fragment 布局放在滚动视图下,但没有帮助。
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
)
}
}
}
问题 1: 在 item.xml
的高度和宽度中使用匹配父项问题二: layout_height="wrap_content" 不能在 GridView 中使用,事实上它不能在 AdapterView 的子类中使用(例如 ListView 和 GridView)。您必须动态计算每个项目的高度,然后相应地设置 gridview 高度。 不用做这么多工作,只需使用带有网格布局的 recyclerview 并将其高度设置为 wrap_content
并在此 recyclerview 中禁用嵌套滚动
recycler.setNestedScrollingEnabled(false);