基于 xml 布局(具有预定义属性)创建的自定义视图(不是 ViewGroup)
Custom view (not ViewGroup) created based on xml layout (with predefined attributes)
我想基于 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
属性。有没有办法通过膨胀布局来做到这一点,还是我必须深入研究属性(包括自定义属性)?
更新
通过“覆盖 src
属性,我的意思是默认情况下图像的来源来自其 xml 文件,但用户可以通过这种方式使用它来在此自定义视图中传递另一个值:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/another_icon" />
要提供 "default" 图像但也允许用户通过指定 android:src
属性覆盖默认值,您可以这样做:
package com.example.Whosebug;
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.Whosebug.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"/>
或者:
<!-- will display `other_image` -->
<com.example.Whosebug.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/other_image"/>
无需在自定义图像视图中膨胀任何内容,也无需创建自定义属性(尽管您当然可以创建自定义属性并根据需要使用它们)。
您可以更新 Java 代码以应用其他 "default" 样式。
我想基于 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
属性。有没有办法通过膨胀布局来做到这一点,还是我必须深入研究属性(包括自定义属性)?
更新
通过“覆盖 src
属性,我的意思是默认情况下图像的来源来自其 xml 文件,但用户可以通过这种方式使用它来在此自定义视图中传递另一个值:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/another_icon" />
要提供 "default" 图像但也允许用户通过指定 android:src
属性覆盖默认值,您可以这样做:
package com.example.Whosebug;
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.Whosebug.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"/>
或者:
<!-- will display `other_image` -->
<com.example.Whosebug.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/other_image"/>
无需在自定义图像视图中膨胀任何内容,也无需创建自定义属性(尽管您当然可以创建自定义属性并根据需要使用它们)。
您可以更新 Java 代码以应用其他 "default" 样式。