我将android CardView扩展为它的可扩展版本,带有标题标题和可以旋转的图标。
CODE
此文件(view_cardview_header.xml)包含ExpandableCardView的标题,它应该是第一个子文件而不是折叠。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
</LinearLayout>
带有自定义xml参数的attrs.xml文件
<resources>
<declare-styleable name="ExpandableCardView">
<attr name="expanded" format="boolean" />
<attr name="headerTitle" format="string" />
<attr name="headerIcon" format="integer" />
</declare-styleable>
</resources>
ExpandableCardView.java类
public class ExpandableCardView extends CardView {
private static final float ROTATION_NORMAL = 0.0f;
private static final float ROTATION_ROTATED = 180f;
private static final float PIVOT_VALUE = 0.5f;
private static final long ROTATE_DURATION = 200;
private boolean isExpanded;
public ExpandableCardView(Context context) {
this(context, null);
}
public ExpandableCardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpandableCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ExpandableCardView, 0, 0);
String titleText = a.getString(R.styleable.ExpandableCardView_headerTitle);
final Drawable drawable = a.getDrawable(R.styleable.ExpandableCardView_headerIcon);
a.recycle();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_cardview_header, this, true);
final LinearLayout parent = (LinearLayout) getChildAt(0);
final RelativeLayout header = (RelativeLayout) parent.getChildAt(0);
final TextView titleTextView = (TextView) header.getChildAt(0);
titleTextView.setText(titleText);
final ImageView toggle = (ImageView) header.getChildAt(1);
if(drawable != null) {
toggle.setImageDrawable(drawable);
}
header.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setExpanded(toggle, !isExpanded);
onExpansionToggled(toggle);
}
});
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if(getChildAt(0) == null || getChildAt(0).equals(child)) {
super.addView(child, index, params);
} else {
((LinearLayout) getChildAt(0)).addView(child);
}
}
private void setExpanded(ImageView toggle, boolean expanded) {
isExpanded = expanded;
final LinearLayout parent = (LinearLayout) getChildAt(0);
final int childCount = parent.getChildCount();
if(expanded) {
toggle.setRotation(ROTATION_ROTATED);
for(int i = childCount - 1; i > 0; i--) {
parent.getChildAt(i).setVisibility(VISIBLE);
}
} else {
toggle.setRotation(ROTATION_NORMAL);
for(int i = 1; i < childCount; i++) {
parent.getChildAt(i).setVisibility(GONE);
}
}
}
private void onExpansionToggled(ImageView toggle) {
RotateAnimation rotateAnimation = new RotateAnimation(ROTATION_ROTATED, ROTATION_NORMAL,
RotateAnimation.RELATIVE_TO_SELF, PIVOT_VALUE, RotateAnimation.RELATIVE_TO_SELF,
PIVOT_VALUE);
rotateAnimation.setDuration(ROTATE_DURATION);
rotateAnimation.setFillAfter(true);
toggle.startAnimation(rotateAnimation);
}
}
用于测试新CardView(fragment_test.xml)的片段布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tecdroid.views.ExpandableCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/card_margin"
android:layout_marginBottom="@dimen/card_margin"
android:layout_marginLeft="@dimen/card_margin"
android:layout_marginRight="@dimen/card_margin"
app:headerTitle="TITLE"
app:headerIcon="@mipmap/ic_action_expand">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First inner child"/>
</com.tecdroid.views.ExpandableCardView>
</LinearLayout>
问题
正如您在图像上看到的那样,第一个内部子项(TextView)未放置在相对布局(标题)下。
首先我认为我必须覆盖onMeasure(int widthMeasureSpec,int heightMeasureSpec)方法,但ExpandableCardView会间接扩展ViewGroup,其中onMeasure(int widthMeasureSpec,int heightMeasureSpec)方法为我完成所有操作。
也许有人弄清楚我忘了或做错了什么。
更新 问题解决了,看到了变化。
答案 0 :(得分:1)
CardView扩展了FrameLayout,你的标题和第一个孩子只是不相关的子视图。要在子项之间建立空间关系,需要使用LinearLayout或RelativeLayout和align- *参数。
答案 1 :(得分:0)
为什么不使用您的cardview和包含子视图的您选择的布局进行复合视图?