创建样式化的 LinearLayout 自定义视图
Create a Styled LinearLayout Custom View
想象一下,您将通过应用程序使用以下卡片设计。标题、按钮、分隔符,然后 space 用于蓝色框指示的动态内容。我们可以在蓝色区域内添加任何我们需要的东西,但用于保存内容的框架是一致的。例如:
Card with Placeholder Region
如果我要在里面放两个 TextView
,它可能看起来像这样,下面是(修剪过的)视图布局:
Card with Two TextViews
<com.google.android.material.card.MaterialCardView>
<LinearLayout android:orientation="vertical">
<LinearLayout android:orientation="horizontal">
<TextView android:text="My Title" />
<com.google.android.material.button.MaterialButton android:text="ACTION" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<LinearLayout android:id="+@id/contentGoesHere">
<TextView android:text="First element" />
<TextView android:text="Second element" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
理想情况下,我想要一个自定义视图,这样开发人员就可以执行以下操作并获得一致的样式,或者以编程方式添加到视图中:
<com.customview.CustomView>
<TextView android:text="First element" />
<TextView android:text="Second element" />
</com.customview.CustomView>
我的问题是,仅仅扩展 LinearLayout
并制作自定义视图是行不通的 - 它会创建布局,但无法表明内部 LinearLayout
是我想要的视图添加到,因此 XML 中添加的任何子视图都将被忽略。
我是否需要制作自定义 ViewGroup
并手动为 LinearLayout
的自定义支架充气(求助!onMeasure 和 onLayout!?)或者是否有更简单的方法制作自定义 LinearLayout
使用此样式框架查看?
My problem is that just extending LinearLayout and making a custom
view wont work - it'll create the layout but there's no way to
indicate that the inner LinearLayout is what I want the views to be
added to, so any subviews added in the XML are ignored.
您可以手动将子视图移入嵌套 LinearLayout
。
例如:
public class CustomView extends LinearLayout {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
final ViewGroup container = inflate(getContext(), R.layout.card_layout, this)
.findViewById(R.id.inner_content_container);
while (getChildCount() > 1) {
final View child = getChildAt(0);
removeView(child);
container.addView(child, child.getLayoutParams());
}
}
}
card_layout.xml
<com.google.android.material.card.MaterialCardView>
<LinearLayout android:orientation="vertical">
<LinearLayout android:orientation="horizontal">
<TextView android:text="My Title" />
<com.google.android.material.button.MaterialButton android:text="ACTION" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<LinearLayout
android:id="@+id/inner_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- content goes here -->
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
...
<com.customview.CustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:text="First element" />
<TextView android:text="Second element" />
</com.customview.CustomView>
想象一下,您将通过应用程序使用以下卡片设计。标题、按钮、分隔符,然后 space 用于蓝色框指示的动态内容。我们可以在蓝色区域内添加任何我们需要的东西,但用于保存内容的框架是一致的。例如:
Card with Placeholder Region
如果我要在里面放两个 TextView
,它可能看起来像这样,下面是(修剪过的)视图布局:
Card with Two TextViews
<com.google.android.material.card.MaterialCardView>
<LinearLayout android:orientation="vertical">
<LinearLayout android:orientation="horizontal">
<TextView android:text="My Title" />
<com.google.android.material.button.MaterialButton android:text="ACTION" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<LinearLayout android:id="+@id/contentGoesHere">
<TextView android:text="First element" />
<TextView android:text="Second element" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
理想情况下,我想要一个自定义视图,这样开发人员就可以执行以下操作并获得一致的样式,或者以编程方式添加到视图中:
<com.customview.CustomView>
<TextView android:text="First element" />
<TextView android:text="Second element" />
</com.customview.CustomView>
我的问题是,仅仅扩展 LinearLayout
并制作自定义视图是行不通的 - 它会创建布局,但无法表明内部 LinearLayout
是我想要的视图添加到,因此 XML 中添加的任何子视图都将被忽略。
我是否需要制作自定义 ViewGroup
并手动为 LinearLayout
的自定义支架充气(求助!onMeasure 和 onLayout!?)或者是否有更简单的方法制作自定义 LinearLayout
使用此样式框架查看?
My problem is that just extending LinearLayout and making a custom view wont work - it'll create the layout but there's no way to indicate that the inner LinearLayout is what I want the views to be added to, so any subviews added in the XML are ignored.
您可以手动将子视图移入嵌套 LinearLayout
。
例如:
public class CustomView extends LinearLayout {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
final ViewGroup container = inflate(getContext(), R.layout.card_layout, this)
.findViewById(R.id.inner_content_container);
while (getChildCount() > 1) {
final View child = getChildAt(0);
removeView(child);
container.addView(child, child.getLayoutParams());
}
}
}
card_layout.xml
<com.google.android.material.card.MaterialCardView>
<LinearLayout android:orientation="vertical">
<LinearLayout android:orientation="horizontal">
<TextView android:text="My Title" />
<com.google.android.material.button.MaterialButton android:text="ACTION" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<LinearLayout
android:id="@+id/inner_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- content goes here -->
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
...
<com.customview.CustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:text="First element" />
<TextView android:text="Second element" />
</com.customview.CustomView>