基于xml布局创建的自定义视图(不是ViewGroup)(具有预定义属性)

时间:2018-02-20 16:13:20

标签: android android-layout android-custom-view

我想使用基于xml文件的一些预定义属性来实现自定义ImageView。为此,我准备了一个包含在merge标签内的布局:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/my_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="center"
        android:src="@drawable/icon" />
</merge>

并扩展ImageVie w class:

public class CustomImageView extends LinearLayout{

    public ImageFormField(Context context) {
        super(context);
        init();
    }

    public ImageFormField(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ImageFormField(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ImageFormField(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        View.inflate(getContext(), R.layout.custom_image_view, this);
    }
}

它到目前为止有效,但我实际上并不需要LinearLayout因为我可以直接从ImageView延伸。通过扩展ImageView,我希望可以从默认布局覆盖src参数。

所以我删除了merge代码,在布局中只有ImageView并尝试了这个:

public class CustomImageView extends AppCompatImageView{

    public ImageFormField(Context context) {
        super(context);
        init();
    }

    public ImageFormField(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ImageFormField(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        View.inflate(getContext(), R.layout.custom_image_view, null); //can't pass root here
    }
}

...但图像根本不显示。我希望能够以这种方式使用我的观点:

<com.my.package.CustomImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

可以覆盖src属性。有没有办法通过膨胀布局来做到这一点,还是我必须深入了解属性(包括自定义属性)?

更新 通过&#34;覆盖src属性我的意思是默认情况下,图像将包含来自其xml文件的源,但是用户可以使用它以此方式在此自定义视图中传递另一个值:

<com.my.package.CustomImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/another_icon" />

1 个答案:

答案 0 :(得分:0)

要提供“默认”图像,但也允许用户通过指定android:src属性来覆盖该默认值,您可以执行以下操作:

package com.example.stackoverflow;

import android.content.Context;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;

public class CustomImageView extends AppCompatImageView {

    public CustomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (getDrawable() == null) {
            setImageResource(R.drawable.default_image);
        }
    }
}

然后你可以像这样使用它:

<!-- will display `default_image` -->
<com.example.stackoverflow.CustomImageView
    android:layout_width="200dp"
    android:layout_height="200dp"/>

或者:

<!-- will display `other_image` -->
<com.example.stackoverflow.CustomImageView
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:src="@drawable/other_image"/>

无需在自定义图像视图中对任何内容进行充气,也无需创建自定义属性(尽管您可以创建自定义属性并在需要时使用它们。)

您可以更新Java代码以应用其他“默认”样式。