Android 如何将 AttributeSet 传递给自定义视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3705144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:27:31  来源:igfitidea点击:

How to pass AttributeSet to custom View

android

提问by atraudes

How do I pass the current AttributeSet to a custom View class? If I use a constructor that only has Context in the arguments, I lose all themes and the ability to use "style" tags in the xml for that custom View.

如何将当前 AttributeSet 传递给自定义 View 类?如果我使用参数中只有 Context 的构造函数,我将失去所有主题以及在该自定义视图的 xml 中使用“样式”标签的能力。

What I've done is create an activity that contains my custom view already in the xml file, and then programmatically create a new one and add it to the layout. What I find is the one that is made in the xml has the proper styling, and the one I create programmatically doesn't.

我所做的是创建一个活动,该活动已在 xml 文件中包含我的自定义视图,然后以编程方式创建一个新视图并将其添加到布局中。我发现在 xml 中制作的那个具有正确的样式,而我以编程方式创建的那个没有。

The difference between the two as far as I can tell is that the system uses the CustomLayout1(Context context, AttributeSet attrs)constructor. The problem is I can't figure out how to get the AttributeSet for the application to pass to this custom view when I create it programmatically.

据我所知,两者之间的区别在于系统使用CustomLayout1(Context context, AttributeSet attrs)构造函数。问题是当我以编程方式创建它时,我无法弄清楚如何让应用程序的 AttributeSet 传递给这个自定义视图。

Here's the Activity:

这是活动:

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class ThemeOne extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LinearLayout layout = (LinearLayout) findViewById(R.id.mainlayout);

        layout.addView(new CustomLayout1(getApplicationContext()));
    }
}

Here's the main xml:

这是主要的xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:id="@+id/mainlayout"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <com.clearsync.test.theme1.CustomLayout1 android:id="@+id/maincustom"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
</LinearLayout>

The custom view class:

自定义视图类:

import com.clearsync.test.theme1.R;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

public class CustomLayout1 extends LinearLayout {
 private Context context = null;

 public CustomLayout1(Context context) {
  super(context);
  this.context = context;
  create();
 }

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

 private void create(){
  LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  layoutInflater.inflate(R.layout.inflateme, this, true);
 }
}

and finally, the custom view xml:

最后,自定义视图 xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <TextView android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:text="Oh, Hewroh..."
  style="?textview_style1" />
</LinearLayout>

采纳答案by Ian G. Clifton

Instead of building it with layout.addView(new CustomLayout1(getApplicationContext())); inflate it with the LayoutInflater in your Activity.

而不是使用 layout.addView(new CustomLayout1(getApplicationContext())); 构建它。使用 Activity 中的 LayoutInflater 对其进行充气。

LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.yourcustomviewxml, layout);

回答by Nimer

Your code creates LinearLayout inside of linear layout for your custom view. Correct way of doing this is changing your custom view xml from:

您的代码在您的自定义视图的线性布局内创建 LinearLayout。这样做的正确方法是从以下位置更改您的自定义视图 xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <TextView android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:text="Oh, Hewroh..."
  style="?textview_style1" />
</LinearLayout>

to

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="wrap_content"
      android:layout_height="wrap_content" 
      android:text="Oh, Hewroh..."
      style="?textview_style1" 
/>
</merge>

回答by Nathan Schwermann

What are you trying to accomplish here? Looks like you have an endless recursive loop here using your create method, as inflate() will call the constructor that takes attributes. Anyways to answer your question you get the attributes in the constructor with the attributes!

你想在这里完成什么?看起来您在这里使用 create 方法有一个无限的递归循环,因为 inflate() 将调用带有属性的构造函数。无论如何,要回答您的问题,您将在具有属性的构造函数中获得属性!

That is the constructor that is called when loading from XML, otherwise it calls one of the other constructors that you supply.

这是从 XML 加载时调用的构造函数,否则它将调用您提供的其他构造函数之一。

One other helpful thing, you can get a reference to the inflater much easier from the static View method. View.inflate :D

另一件有用的事情是,您可以从静态 View 方法中更轻松地获得对充气机的引用。查看.inflate :D