在android中以编程方式创建视图时如何传递AttributeSet
Posted
技术标签:
【中文标题】在android中以编程方式创建视图时如何传递AttributeSet【英文标题】:How to pass AttributeSet when creating view programmatically in android 【发布时间】:2015-05-15 16:41:05 【问题描述】:然后我像水平视图一样以编程方式创建,如何以编程方式传递 AttributeSet。
我的构造函数如下所示:
public HorizontalListView(Context context, AttributeSet attrs)
super(context, attrs);
我试过这个:
mHlvSimpleList= new HorizontalListView(mcontext,R.style.niceview);
错误:
构造函数 HorizontalListView(Context, int) 未定义
在 style.xml 中
<style name="niceview">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
horizontalistview构造函数匹配参数如何传递AttributeSet?
【问题讨论】:
***.com/a/25457076/1105214 我发现最简单的方法是简单地为自定义视图制作布局并对其进行膨胀,如果您有多个略有不同的实例,只需创建一个基本样式并使用 @987654325 对其进行子类化@,<style="DeceptaDroid" parent="Droid">
【参考方案1】:
Context
和 AttributeSet
的构造函数用于当您的视图从 xml 膨胀时。您不应该使用它来创建对象。您应该使用带有Context
作为参数的构造函数。
AttributeSet
是接口,你可以创建then的实例并实现所有方法,如下所示:
AttributeSet attrs = new AttributeSet()
@Override
public int getAttributeCount()
return 0;
@Override
public String getAttributeName(int index)
return null;
@Override
public String getAttributeValue(int index)
return null;
@Override
public String getAttributeValue(String namespace, String name)
return null;
@Override
public String getPositionDescription()
return null;
@Override
public int getAttributeNameResource(int index)
return 0;
@Override
public int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue)
return 0;
@Override
public boolean getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue)
return false;
@Override
public int getAttributeResourceValue(String namespace, String attribute, int defaultValue)
return 0;
@Override
public int getAttributeIntValue(String namespace, String attribute, int defaultValue)
return 0;
@Override
public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue)
return 0;
@Override
public float getAttributeFloatValue(String namespace, String attribute, float defaultValue)
return 0;
@Override
public int getAttributeListValue(int index, String[] options, int defaultValue)
return 0;
@Override
public boolean getAttributeBooleanValue(int index, boolean defaultValue)
return false;
@Override
public int getAttributeResourceValue(int index, int defaultValue)
return 0;
@Override
public int getAttributeIntValue(int index, int defaultValue)
return 0;
@Override
public int getAttributeUnsignedIntValue(int index, int defaultValue)
return 0;
@Override
public float getAttributeFloatValue(int index, float defaultValue)
return 0;
@Override
public String getIdAttribute()
return null;
@Override
public String getClassAttribute()
return null;
@Override
public int getIdAttributeResourceValue(int defaultValue)
return 0;
@Override
public int getStyleAttribute()
return 0;
;
并使用它
TextView textView = new TextView(this, attrs);
但是这是不正确的方式。
您应该使用视图中的方法来设置视图的属性。
例如设置 LayoutParams 有两种方法
首先通过方法setLayoutParams()
view.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
将视图添加到 ViewGroup 的第二个;
viewGroup.addView(yourView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
当您拥有或想要将视图添加到例如 RelativeLayout
时,您应该使用与此 ViewGroup 相关的 LayoutParams
。是RelativeLayout.LayoutParams
【讨论】:
我关心的是,如何在android的构造函数中传递AttributeSet。 您不应该这样做,当您在 xml 中创建视图时,创建者会使用具有两个参数的构造函数 如果你想手动创建你的对象,你必须使用以Context
为参数的构造函数并通过方法设置你的属性。
但是在Horizontal Constructore 中是在上下文中接受两个参数一个,而另一个是AttributeSet,因此,如何在没有attrs 的情况下以编程方式创建HorizontalListView 视图,但它需要attrs 参数。
您自己实现的 AttributeSet 接口将不起作用。 Android 会抛出 java.lang.ClassCastException: 我有办法从 xml 文件中获取 AttributeSet。
XmlPullParser parser = getResources().getXml(R.xml.test);
try
parser.next();
parser.nextTag();
catch (Exception e)
e.printStackTrace();
AttributeSet attr = Xml.asAttributeSet(parser);
int count = attr.getAttributeCount();
如果计数值大于0,则表示你得到了一个正确的AttributeSet。
我的 xml/test.xml 是这样的:
<?xml version="1.0" encoding="utf-8"?>
<com.galoisli.myapplication.MyListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/listView"
android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
【讨论】:
我对这个 android 开发还是很陌生。为什么这不是公认的答案?这似乎很有意义.... @HumbleWebDev B/c 确实不需要重新实现框架已经提供的功能 -MyListView
已经在布局文件中,因此它的膨胀将通过属性设置为它的“通货膨胀”构造函数(MyListView(Context c, AttributeSet a
)。除了对框架进行一些黑客攻击之外,我真的想不出任何其他用途,但可能是错误的。
@HumbleWebDev 该框架将这种代码隐藏在私有方法中是有充分理由的——这样用户就可以从它的实现中抽象出来。一个应用程序的这些 sn-ps 越多,它的向后兼容性就越差,就越脆弱。
这应该是公认的答案!
在 Android 中,您可以在 XML 中设置属性,但类本身没有等效的 setter/getter。因此,如果您在代码中创建视图/首选项,那么您将陷入困境。一个示例是 Preference 中的 allowDividerBelow。【参考方案3】:
我在处理一个忘记实现SomeView(Context)
构造函数并且只有SomeView(Context, AttributeSet)
可用的视图时遇到了这个问题。不过,从 source code of ViewGroup 看来,SomeView(context)
将等同于 SomeView(context, null)
。
【讨论】:
【参考方案4】:您可以创建引用自定义样式的属性。然后你应该能够使用
来实例化它mHlvSimpleList= new HorizontalListView(mcontext, R.attr.niceview);
那里有一个完整的例子 https://gist.github.com/romannurik/7026222
【讨论】:
该要点显示正在使用的 3 个参数View(Context, AttributeSet, int)
其中 R.attr.niceview
是指向默认样式的属性以上是关于在android中以编程方式创建视图时如何传递AttributeSet的主要内容,如果未能解决你的问题,请参考以下文章
在android中以编程方式将EditText视图约束到复选框?
如何在android中以编程方式查找TextView的文本区域(高度/宽度)