简体   繁体   English

在XML中创建自定义布局以在代码或其他布局xml中初始化

[英]Create custom layout in XML to initialize in code or in another layout xml

I have encountered an issue i am trying to resolve (or understand better the way it should be done) in creation of custom Layout in Android. 我在Android中创建自定义布局时遇到了试图解决(或更好地理解应做的方式)的问题

I want to create a custom RelativeLayout class for my use, which is defined in a layout XML file. 我想创建一个自定义的RelativeLayout类供我使用,该类在布局XML文件中定义。

my_relative_layout.xml my_relative_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.mypackage.MyRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:scaleType="fitStart"
        android:src="@drawable/my_drawable"/>
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/title_gray"
        android:layout_below="@id/image_view"
        android:gravity="center"
        android:text="@string/placeholder" />
</com.mypackage.MyRelativeLayout>

Usage 用法

  public class MyRelativeLayout extends RelativeLayout {
        private AttributeSet attrs;
        private ImageView imageView;
        private TextView textView;

        public MyRelativeLayout(Context context) {
            super(context);
        }

        public MyRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.attrs = attrs;
        }

        public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.attrs = attrs;
        }

        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            if (attrs != null) {
                TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.MyRelativeLayout, 0, 0);
                drawableResource = a.getResourceId(R.styleable.MyRelativeLayout.image_view, 0);
                a.recycle();
            }
            imageView = (ImageView) findViewById(R.id.image_view);
            textView = (TextView) findViewById(R.id.text_view);

            if (drawableResource != 0 && imageView != null) {
                imageView.setImageResource(drawableResource);
            }
        }
    }

My issue is that i want to initialise this layout both in another XML and in code. 我的问题是我想在另一个XML和代码中初始化此布局。 But as I wrote my class and XML, i can only use it in code by doing: 但是当我编写类和XML时,我只能通过执行以下操作在代码中使用它:

myLayout = (MyRelativeLayout) LayoutInflater.from(this.getActivity()).inflate(R.layout.my_relative_layout, container, false);

When writing the following in another XML causes the onFinishInflate to fail on getViewById (returns null) and the childrenCount is 0 用其他XML编写以下内容时,会导致onFinishInflate在getViewById上失败(返回null),并且childrenCount为0

<com.mypackage.MyRelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@id/another_layout"
    app:image_view="@drawable/my_image" />

and doing the following, won't let me configure the custom image_view attribute. 并执行以下操作,就不会让我配置自定义image_view属性。

<include layout="@layout/my_relative_layout"/>

To fix that, i can change the custom layout XML root element to be of type RelativeLayout and add the following to the beginning of onFinishInflate method: 为了解决这个问题,我可以将自定义布局XML根元素更改为RelativeLayout类型,并将以下内容添加到onFinishInflate方法的开头:

LayoutInflater.from(getContext()).inflate(R.layout.my_relative_layout, this, true);

But the XML won't reference my class. 但是XML不会引用我的课程。
My questions are, 我的问题是
1. Am i missing something in the definition of the custom layout? 1.我在自定义布局的定义中缺少什么吗?
2. What is the correct definition for custom layout? 2.自定义布局的正确定义是什么?

Thank you in advance! 先感谢您!

First you should use the styled attributes in the contractor as shown in this example. 首先,您应该在承包商中使用样式化的属性,如示例所示。

How can you expect from MyRelativeLayout that defined as fallow: 您如何对MyRelativeLayout定义为休假的期望:

<com.mypackage.MyRelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@id/another_layout"
    app:image_view="@drawable/my_image" />

To be aware of views that are defined in my_relative_layout.xml ? 要知道my_relative_layout.xml中定义的my_relative_layout.xml吗?

To make it work you should create a costume layout and add it to com.mypackage.MyRelativeLayout manually. 要使其工作,您应该创建一个服装布局并将其手动添加到com.mypackage.MyRelativeLayout

Some thing like that: 像这样的东西:

costume_layout.xml costume_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:scaleType="fitStart"
        android:src="@drawable/my_drawable"/>
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/title_gray"
        android:layout_below="@id/image_view"
        android:gravity="center"
        android:text="@string/placeholder" />
</RelativeLayout>

Your costume view 您的服装视角

public class MyRelativeLayout extends RelativeLayout {
        private AttributeSet attrs;
        private ImageView imageView;
        private TextView textView;

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

        public MyRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init(Context context){
            LayoutInflater.from(context).inflate(R.layout.costume_layout, this);
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM