在创建自定义视图时,我注意到许多人似乎这样做:
public MyView(Context context) {
super(context);
// this constructor used when programmatically creating view
doAdditionalConstructorWork();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// this constructor used when creating view through XML
doAdditionalConstructorWork();
}
private void doAdditionalConstructorWork() {
// init variables etc.
}
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,构造函数MyView(Context context, AttributeSet attrs, int defStyle)怎么样?我不确定它在哪里使用,但我在超级课程中看到它.我需要它,它在哪里使用?
我做了如下
1)创建一个风格
<declare-styleable name="Viewee">
<attr name="linkedView" format="reference"/>
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
2)定义自定义视图布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffc0">
<TextView
android:id="@+id/custom_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="[text]"
/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
3)创建所需的类
public class Viewee extends LinearLayout
{
public Viewee(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
View.inflate(context, R.layout.viewee, this);
TextView textView = (TextView) findViewById(R.id.custom_text);
TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.Viewee);
int id = typedArray.getResourceId(R.styleable.Viewee_linkedView, 0);
if (id != 0)
{
View view = findViewById(id);
textView.setText(((TextView) view).getText().toString());
}
typedArray.recycle();
}
}
Run Code Online (Sandbox Code Playgroud)
最后是在下面的活动中
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.ns"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvTest"
android:layout_width="fill_parent"
android:layout_height="wrap_content" …Run Code Online (Sandbox Code Playgroud) 我创建了一个自定义复合视图 - 视图加载,没有崩溃,到目前为止一切都很好.
现在,我计划在我的应用程序中使用此视图多次,因此视图需要一种样式.
我在attr.xml文件中声明了它的样式
<declare-styleable name="MyCustomView">
<attr name="ff_label" format="string" />
<attr name="ff_fieldText" format="string" />
</declare-styleable>
<declare-styleable name="MyCustomViewStyle">
<attr name="customViewStyle" format="reference" />
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
然后我去了我的主题文件并在里面写了这个
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
//bunch of other stuff
<item name="customViewStyle">@style/customViewStyle</item>
</style>
Run Code Online (Sandbox Code Playgroud)
然后在我的android清单中我宣布
<application
android:name="com.my.app.App"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
Run Code Online (Sandbox Code Playgroud)
然后在我写的styles.xml文件中
<style name="customViewStyleStyle" parent="@android:style/Widget.EditText">
<item name="android:paddingBottom">@dimen/space_between_adjacent_widgets_vertical</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="ff_label">@string/default_label_text</item>
<item name="ff_fieldText">@string/default_label_text</item>
</style>
Run Code Online (Sandbox Code Playgroud)
我的问题:我的OWN属性被认可得很好.
为什么标记的属性被"android:..."忽略了? …
我有一个自定义的TextView,它实现了三个View构造函数(nb,这是我在Android应用程序中的第一次尝试):
public class DynamicGeometryTextView extends TextView {
public DynamicGeometryTextView (Context con) { super(con); }
public DynamicGeometryTextView (Context con, AttributeSet attrs) {
super(con, attrs);
}
public DynamicGeometryTextView (Context con, AttributeSet attrs, int style) {
super(con, attrs, style);
}
Run Code Online (Sandbox Code Playgroud)
这是一个非静态内部类,因为它需要从外部类访问实例数据.它出现在.xml布局中:
<view class="cogdis.chalkboard.DisplayText$DynamicGeometryTextView"
android:id="@+id/chalkboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)
一切都编译和安装很好,但在运行时:
Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class cogdis.chalkboard.DisplayText$DynamicGeometryTextView
at android.view.LayoutInflater.createView(LayoutInflater.java:596)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
at android.app.Activity.setContentView(Activity.java:1867)
at cogdis.chalkboard.DisplayText.onCreate(DisplayText.java:26)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at …Run Code Online (Sandbox Code Playgroud)