如何在 Kotlin 的卡片视图中设置属性
How to set Attributes in a Card View in Kotlin
我正在设计一个 Feed,我希望在其中以卡片形式发布帖子,我使用 Google 的设计库实现了这些帖子。我已经创建了我的布局,但由于帖子将被动态获取,因此我想在 Kotlin 中动态创建我的布局。为此,我创建了一个函数,它将图像、标题、描述作为参数,并将 return 卡片视图 Object。
为了在 CardView 中设置属性,我尝试了 layoutParams 但使用它只是让我的应用程序崩溃了
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
在这段代码中,我尝试了所有布局类型 Linear、Relative、Coordinator 甚至 ViewGroup,但我的应用程序每次都崩溃。
这是我的布局:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Home"
android:background="@color/DirtyWhite"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:tag="FEED">
//This is the card view which I want to create dynamically
<android.support.v7.widget.CardView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:elevation="50dp"
app:cardCornerRadius="10dp">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:clipToPadding="false">
<ImageView android:layout_width="match_parent"
android:layout_height="180dp"
android:src="@drawable/sample"
android:scaleType="centerCrop"
android:layout_marginTop="-10dp"
android:layout_marginStart="-10dp"
android:layout_marginEnd="-10dp"
android:layout_marginBottom="-10dp"
android:adjustViewBounds="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.TextAppearance.AppCompat.Title"
android:text="This is a part of Material Design."
android:ellipsize="end"
android:maxLines="1"
android:layout_marginTop="16dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Body2"
android:text="This is a part of Material Design. This is a part of Material Design. This is a part of Material Design. "
android:ellipsize="end"
android:textColor="@color/realGray"
android:maxLines="2"
android:layout_marginTop="8dp"
/>
<RelativeLayout android:layout_width="match_parent"
android:layout_marginTop="8dp"
android:layout_height="wrap_content">
<RatingBar android:layout_width="wrap_content" android:layout_height="wrap_content"
android:numStars="5"
android:rating="3"
android:isIndicator="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
style="@style/Base.Widget.AppCompat.RatingBar.Small"/>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/ic_favorite_border_black_24dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order Now"
android:background="@drawable/rounded_card_button_small"
android:textColor="@color/DirtyWhite"
android:minHeight="0dp"
android:minWidth="0dp"
android:padding="5dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
我试过这段代码来动态创建布局:
(注意:此代码仅用于创建不包括评级栏和其他操作按钮的基本卡片)
fun createAdsPost(view: View, photo: ImageView, titleText: String, descText: String): CardView {
val cardView = CardView(view.context)
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
cardView.layoutParams = cardViewParam
cardViewParam.width = LinearLayout.LayoutParams.MATCH_PARENT
cardViewParam.height = LinearLayout.LayoutParams.WRAP_CONTENT
cardViewParam.setMargins(dpToPx(5, view), dpToPx(5, view), dpToPx(5, view), dpToPx(5, view))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cardView.elevation = dpToPx(50, view).toFloat()
}
cardView.apply {
radius = dpToPx(10, view).toFloat()
this.layoutParams = cardViewParam
}
val linear1 = LinearLayout(view.context)
linear1.orientation = LinearLayout.VERTICAL
linear1.setPadding(dpToPx(10, view), dpToPx(10, view), dpToPx(10, view), dpToPx(10, view))
linear1.clipToPadding = false
val linear1Param = linear1.layoutParams as LinearLayout.LayoutParams
linear1Param.width = LinearLayout.LayoutParams.MATCH_PARENT
linear1Param.height = LinearLayout.LayoutParams.WRAP_CONTENT
linear1.layoutParams = linear1Param
photo.scaleType = ImageView.ScaleType.CENTER_CROP
photo.adjustViewBounds = true
val photoParams = photo.layoutParams as LinearLayout.LayoutParams
photoParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = dpToPx(180, view)
topMargin = dpToPx(-10, view)
bottomMargin = dpToPx(-10, view)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
photoParams.marginStart = dpToPx(-10, view)
photoParams.marginEnd = dpToPx(-10, view)
}
linear1.addView(photo)
val title = TextView(view.context)
title.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 1
text = titleText
}
val titleTextParams = title.layoutParams as LinearLayout.LayoutParams
titleTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(16, view)
}
linear1.addView(title)
val desc = TextView(view.context)
desc.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 2
text = descText
setTextColor(Color.parseColor("#626567"))
}
val descTextParams = desc.layoutParams as LinearLayout.LayoutParams
descTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(8, view)
}
linear1.addView(desc)
cardView.addView(linear1)
return cardView
}
当我使用这些代码时,我的应用程序崩溃了。我尝试调试我的代码,发现第一个错误在 CardView 的 layoutParams
中。
简而言之,我想知道如何在卡片视图中设置属性
另外,请告诉我这是创建动态布局的唯一方法还是有更有效的方法。我是 Android 开发中的新手。
我想建议一件事,如果您的要求是动态创建视图,那么您只需尝试一件事:
1) 为动态视图制作一个单独的布局文件
2) 使用:
膨胀该布局
val layoutInflater = getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layoutInflater!!.inflate(R.layout.your_layout_file)
3) 现在您将拥有视图,然后您只需使用类似以下内容的方式访问布局视图:
view.findViewById(you view id)
4) 现在您将能够轻松地动态创建和访问您的视图
Note:
getContent() : will come according to your usage on fragment or in activity, so need to change it accordingly
same as inflate method, use parameter according to your requirement
您正在将 LayoutParams
转换为 CoordinatorLayout.LayoutParams
,而您正在动态创建一个没有父视图的视图,我认为这就是问题所在。
如果您要动态创建视图,那么您还应该根据其父容器创建新的 LayoutParams
。
例如,如果您想在 LinearLayout
中添加 CardView
,则 LayoutParams
应如下所示:
val cardView = CardView(view.context)
val cardViewParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
it.setMargins(dpToPx(5, view), dpToPx(5, view), dpToPx(5, view), dpToPx(5, view))
}
cardView.apply {
radius = dpToPx(10, view).toFloat()
this.layoutParams = cardViewParam
}
...
...
val linear1 = LinearLayout(view.context)
val linear1Param = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
...
...
cardView.addView(linear1)
对于 linear1
,我们采用了 FrameLayout.LayoutParams
,因为在我们的例子中,我们将把它添加为 CardView
的子项,这是一个扩展的 FrameLayout
。
我正在设计一个 Feed,我希望在其中以卡片形式发布帖子,我使用 Google 的设计库实现了这些帖子。我已经创建了我的布局,但由于帖子将被动态获取,因此我想在 Kotlin 中动态创建我的布局。为此,我创建了一个函数,它将图像、标题、描述作为参数,并将 return 卡片视图 Object。
为了在 CardView 中设置属性,我尝试了 layoutParams 但使用它只是让我的应用程序崩溃了
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
在这段代码中,我尝试了所有布局类型 Linear、Relative、Coordinator 甚至 ViewGroup,但我的应用程序每次都崩溃。
这是我的布局:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Home"
android:background="@color/DirtyWhite"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:tag="FEED">
//This is the card view which I want to create dynamically
<android.support.v7.widget.CardView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:elevation="50dp"
app:cardCornerRadius="10dp">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:clipToPadding="false">
<ImageView android:layout_width="match_parent"
android:layout_height="180dp"
android:src="@drawable/sample"
android:scaleType="centerCrop"
android:layout_marginTop="-10dp"
android:layout_marginStart="-10dp"
android:layout_marginEnd="-10dp"
android:layout_marginBottom="-10dp"
android:adjustViewBounds="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.TextAppearance.AppCompat.Title"
android:text="This is a part of Material Design."
android:ellipsize="end"
android:maxLines="1"
android:layout_marginTop="16dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Body2"
android:text="This is a part of Material Design. This is a part of Material Design. This is a part of Material Design. "
android:ellipsize="end"
android:textColor="@color/realGray"
android:maxLines="2"
android:layout_marginTop="8dp"
/>
<RelativeLayout android:layout_width="match_parent"
android:layout_marginTop="8dp"
android:layout_height="wrap_content">
<RatingBar android:layout_width="wrap_content" android:layout_height="wrap_content"
android:numStars="5"
android:rating="3"
android:isIndicator="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
style="@style/Base.Widget.AppCompat.RatingBar.Small"/>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/ic_favorite_border_black_24dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order Now"
android:background="@drawable/rounded_card_button_small"
android:textColor="@color/DirtyWhite"
android:minHeight="0dp"
android:minWidth="0dp"
android:padding="5dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
我试过这段代码来动态创建布局: (注意:此代码仅用于创建不包括评级栏和其他操作按钮的基本卡片)
fun createAdsPost(view: View, photo: ImageView, titleText: String, descText: String): CardView {
val cardView = CardView(view.context)
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
cardView.layoutParams = cardViewParam
cardViewParam.width = LinearLayout.LayoutParams.MATCH_PARENT
cardViewParam.height = LinearLayout.LayoutParams.WRAP_CONTENT
cardViewParam.setMargins(dpToPx(5, view), dpToPx(5, view), dpToPx(5, view), dpToPx(5, view))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cardView.elevation = dpToPx(50, view).toFloat()
}
cardView.apply {
radius = dpToPx(10, view).toFloat()
this.layoutParams = cardViewParam
}
val linear1 = LinearLayout(view.context)
linear1.orientation = LinearLayout.VERTICAL
linear1.setPadding(dpToPx(10, view), dpToPx(10, view), dpToPx(10, view), dpToPx(10, view))
linear1.clipToPadding = false
val linear1Param = linear1.layoutParams as LinearLayout.LayoutParams
linear1Param.width = LinearLayout.LayoutParams.MATCH_PARENT
linear1Param.height = LinearLayout.LayoutParams.WRAP_CONTENT
linear1.layoutParams = linear1Param
photo.scaleType = ImageView.ScaleType.CENTER_CROP
photo.adjustViewBounds = true
val photoParams = photo.layoutParams as LinearLayout.LayoutParams
photoParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = dpToPx(180, view)
topMargin = dpToPx(-10, view)
bottomMargin = dpToPx(-10, view)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
photoParams.marginStart = dpToPx(-10, view)
photoParams.marginEnd = dpToPx(-10, view)
}
linear1.addView(photo)
val title = TextView(view.context)
title.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 1
text = titleText
}
val titleTextParams = title.layoutParams as LinearLayout.LayoutParams
titleTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(16, view)
}
linear1.addView(title)
val desc = TextView(view.context)
desc.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 2
text = descText
setTextColor(Color.parseColor("#626567"))
}
val descTextParams = desc.layoutParams as LinearLayout.LayoutParams
descTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(8, view)
}
linear1.addView(desc)
cardView.addView(linear1)
return cardView
}
当我使用这些代码时,我的应用程序崩溃了。我尝试调试我的代码,发现第一个错误在 CardView 的 layoutParams
中。
简而言之,我想知道如何在卡片视图中设置属性
另外,请告诉我这是创建动态布局的唯一方法还是有更有效的方法。我是 Android 开发中的新手。
我想建议一件事,如果您的要求是动态创建视图,那么您只需尝试一件事:
1) 为动态视图制作一个单独的布局文件 2) 使用:
膨胀该布局val layoutInflater = getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layoutInflater!!.inflate(R.layout.your_layout_file)
3) 现在您将拥有视图,然后您只需使用类似以下内容的方式访问布局视图:
view.findViewById(you view id)
4) 现在您将能够轻松地动态创建和访问您的视图
Note:
getContent() : will come according to your usage on fragment or in activity, so need to change it accordingly
same as inflate method, use parameter according to your requirement
您正在将 LayoutParams
转换为 CoordinatorLayout.LayoutParams
,而您正在动态创建一个没有父视图的视图,我认为这就是问题所在。
如果您要动态创建视图,那么您还应该根据其父容器创建新的 LayoutParams
。
例如,如果您想在 LinearLayout
中添加 CardView
,则 LayoutParams
应如下所示:
val cardView = CardView(view.context)
val cardViewParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
it.setMargins(dpToPx(5, view), dpToPx(5, view), dpToPx(5, view), dpToPx(5, view))
}
cardView.apply {
radius = dpToPx(10, view).toFloat()
this.layoutParams = cardViewParam
}
...
...
val linear1 = LinearLayout(view.context)
val linear1Param = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
...
...
cardView.addView(linear1)
对于 linear1
,我们采用了 FrameLayout.LayoutParams
,因为在我们的例子中,我们将把它添加为 CardView
的子项,这是一个扩展的 FrameLayout
。