如何在 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