如何在Android上创建具有内部框架布局的自定义CardView

如何在Android上创建具有内部框架布局的自定义CardView,android,android-layout,android-cardview,android-framelayout,Android,Android Layout,Android Cardview,Android Framelayout,我需要在CardView中添加边框,我发现这样做的方法(在stackoverflow中)是在内部创建一个FrameLayout,并向其添加一个形状背景。这种方法工作得很好,但现在我需要将其扩展到自定义布局,以避免每次使用此cardviewWithBorders时重复此代码 当前代码如下所示: <android.support.v7.widget.CardView android:layout_width="match_parent" android:

我需要在CardView中添加边框,我发现这样做的方法(在stackoverflow中)是在内部创建一个FrameLayout,并向其添加一个形状背景。这种方法工作得很好,但现在我需要将其扩展到自定义布局,以避免每次使用此cardviewWithBorders时重复此代码

当前代码如下所示:

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:elevation="4dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_border_corner_radius"
            android:padding="16dp">

            <EditText
                android:id="@+id/fieldInput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                android:lineSpacingMultiplier="1.5"
                android:textAppearance="@style/LatoRegular"
                android:textSize="16sp"
                tools:hint="Type in your E-mail" />
        </FrameLayout>
    </android.support.v7.widget.CardView>
<com.example.BorderCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <content goes here />

</com.example.BorderCardView>

我只想拥有CardView的一个组件和FrameLayout,我可以这样使用:

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:elevation="4dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_border_corner_radius"
            android:padding="16dp">

            <EditText
                android:id="@+id/fieldInput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/transparent"
                android:lineSpacingMultiplier="1.5"
                android:textAppearance="@style/LatoRegular"
                android:textSize="16sp"
                tools:hint="Type in your E-mail" />
        </FrameLayout>
    </android.support.v7.widget.CardView>
<com.example.BorderCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <content goes here />

</com.example.BorderCardView>

我能做些什么来实现这种行为?

您很幸运,您的“内部”视图是一个
FrameLayout
,并且
CardView
扩展了FrameLayout,因为这意味着您不必担心子视图的确切类型”
LayoutParams
对象

public class BorderCardView extends CardView {

    public BorderCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        FrameLayout.LayoutParams params = 
                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);

        FrameLayout frame = new FrameLayout(getContext());
        frame.setLayoutParams(params);
        frame.setBackground(/* your background drawable */);
        frame.setPadding(/* your left/top/right/bottom padding */);

        while (getChildCount() > 0) {
            View child = getChildAt(0);

            FrameLayout.LayoutParams childParams =
                    (FrameLayout.LayoutParams) child.getLayoutParams();

            removeView(child);
            frame.addView(child);

            child.setLayoutParams(childParams);
        }

        addView(frame);
    }
}
您在这里所做的是动态创建“内部”框架布局,然后循环布局中的所有子项,将它们从
CardView
中删除,并将它们添加到
FrameLayout
,然后最后将“内部”框架添加到
CardView

您的“内部”视图是一个
FrameLayout
,它扩展了FrameLayout,因为这意味着您不必担心子视图的
LayoutParams
对象的确切类型

public class BorderCardView extends CardView {

    public BorderCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        FrameLayout.LayoutParams params = 
                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);

        FrameLayout frame = new FrameLayout(getContext());
        frame.setLayoutParams(params);
        frame.setBackground(/* your background drawable */);
        frame.setPadding(/* your left/top/right/bottom padding */);

        while (getChildCount() > 0) {
            View child = getChildAt(0);

            FrameLayout.LayoutParams childParams =
                    (FrameLayout.LayoutParams) child.getLayoutParams();

            removeView(child);
            frame.addView(child);

            child.setLayoutParams(childParams);
        }

        addView(frame);
    }
}

这里要做的是动态创建“内部”
FrameLayout
,然后循环布局中的所有子项,将它们从
cardwiew
中删除,并将它们添加到
FrameLayout
中,最后添加“内部”“卡视图
的框架

工作得很好!工作得很好!