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

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

我将 android CardView 扩展为可扩展版本,带有标题标题和可以旋转的图标。

代码

此文件(view_cardview_header.xml)包含 ExpandableCardView 的 header ,它应该是第一个子级且不折叠。

<?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 布局(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)没有放置在相对布局(Header)下。

首先,我认为我必须重写 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法,但是 ExpandableCardView 间接扩展了 ViewGroup,其中 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法为我完成了这一切。

也许有人知道我忘记了什么,或者做错了什么。

更新 问题已解决,请参阅更改。

最佳答案

CardView 扩展了 FrameLayout,您的 header 和第一个 subview 只是不相关的 subview 。要在子项之间建立空间关系,您需要使用带有align-*参数的LinearLayout或RelativeLayout。

关于java - Android:扩展CardView可以扩展哪些内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42718388/

相关文章:

java - 在android开发中使用lambdaj库

java - JAXB - 解码 OutOfMemory : Java Heap Space

java - 如何在 IntelliJ IDEA 中自动完成 lambda?

java - 私有(private)方法的 Junit 测试

java - Eclipse(和 m2eclipse)的问题

android - 如何检查 Google Play 服务是否已从 android 中的代码启用/禁用

java - Java中的二进制搜索代码无法运行

java - 谷歌应用引擎: Map parameter becomes JSonMap

Java将XML转换为JSON并判断是数组还是对象

c# - DataContractSerializer 创建的 XML 格式