Android:扩展CardView哪些内容可以扩展

时间:2017-03-10 12:25:02

标签: java android xml android-custom-view android-cardview

我将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>

Result on Emulator

问题

正如您在图像上看到的那样,第一个内部子项(TextView)未放置在相对布局(标题)下。

首先我认为我必须覆盖onMeasure(int widthMeasureSpec,int heightMeasureSpec)方法,但ExpandableCardView会间接扩展ViewGroup,其中onMeasure(int widthMeasureSpec,int heightMeasureSpec)方法为我完成所有操作。

也许有人弄清楚我忘了或做错了什么。

更新 问题解决了,看到了变化。

2 个答案:

答案 0 :(得分:1)

CardView扩展了FrameLayout,你的标题和第一个孩子只是不相关的子视图。要在子项之间建立空间关系,需要使用LinearLayout或RelativeLayout和align- *参数。

答案 1 :(得分:0)

为什么不使用您的cardview和包含子视图的您选择的布局进行复合视图?