如何初始化依赖于视图属性的东西
How to initialize stuff that depends on the view’s attributes
说我有这个 class MyView
:
public class MyView extends GLSurfaceView {
private MyRenderer mRenderer;
public MyView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
init(ctx);
}
private void init(Context ctx) {
mRenderer = new MyRenderer(ctx);
setRenderer(mRenderer);
}
@Override
public void setBackground(Drawable background) {
mRenderer.setBackground(background);
}
}
这是由 MyActivity
膨胀的,像这样:
public class MyActivity extends Activity {
private MyView mView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
protected void init() {
setContentView(R.layout.my_layout);
mView = (MyView) findViewById(R.id.my_view);
}
}
据我所知,setBackground
在 setContentView
中被 inflater 调用,在 MyView
中调用 init
之前,因此 mRenderer
尚未初始化还。
好像是第 22 条军规,因为如果没有视图的初始化就无法设置视图的属性,这是在设置属性之后发生的。
这是布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/background" >
<com.developer.app.MyView
android:id="@+id/my_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/background"
/>
<TextView
android:id="@+id/left_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/left_arrow"
/>
<TextView
android:id="@+id/right_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/right_arrow"
/>
<TextView
android:id="@+id/home_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/home"
/>
</RelativeLayout>
你已经初始化了它的三个函数,例如 xml 和 java 就是你正在做的。
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
}
我从你的问题中了解到的。您需要 oncreate() 中的视图属性。但不能这样做。原因是 UI 还没有初始化。有解决办法。
这 link 可能会有所帮助。
getWidth() and getHeight() of View returns 0
你是对的。如果解析了 android:background
属性,则从 View
的构造函数调用 setBackground()
。在你的情况下,它在这里调用:
super(ctx, attrs);
如果要将背景设置为mRenderer
,可以在init
:
中进行
private void init(Context ctx) {
mRenderer = new MyRenderer(ctx);
setRenderer(mRenderer);
final Drawable background = getBackground();
if (background != null) {
mRenderer.setBackground(background);
}
}
并在 setBackground
中添加一个 null-check,因为在将某些值设置为 mRenderer
之前,可以从超类的构造函数中调用此方法
@Override
public void setBackground(Drawable background) {
if (mRenderer != null) {
mRenderer.setBackground(background);
}
}
说我有这个 class MyView
:
public class MyView extends GLSurfaceView {
private MyRenderer mRenderer;
public MyView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
init(ctx);
}
private void init(Context ctx) {
mRenderer = new MyRenderer(ctx);
setRenderer(mRenderer);
}
@Override
public void setBackground(Drawable background) {
mRenderer.setBackground(background);
}
}
这是由 MyActivity
膨胀的,像这样:
public class MyActivity extends Activity {
private MyView mView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
protected void init() {
setContentView(R.layout.my_layout);
mView = (MyView) findViewById(R.id.my_view);
}
}
据我所知,setBackground
在 setContentView
中被 inflater 调用,在 MyView
中调用 init
之前,因此 mRenderer
尚未初始化还。
好像是第 22 条军规,因为如果没有视图的初始化就无法设置视图的属性,这是在设置属性之后发生的。
这是布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/background" >
<com.developer.app.MyView
android:id="@+id/my_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/background"
/>
<TextView
android:id="@+id/left_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/left_arrow"
/>
<TextView
android:id="@+id/right_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/right_arrow"
/>
<TextView
android:id="@+id/home_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/home"
/>
</RelativeLayout>
你已经初始化了它的三个函数,例如 xml 和 java 就是你正在做的。
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setTextColor(Color.parseColor("#4789da"));
this.setBackgroundResource(R.drawable.edittext_back);
this.setTextSize(18);
this.setPadding(5,5,5,5);
}
}
我从你的问题中了解到的。您需要 oncreate() 中的视图属性。但不能这样做。原因是 UI 还没有初始化。有解决办法。 这 link 可能会有所帮助。
getWidth() and getHeight() of View returns 0
你是对的。如果解析了 android:background
属性,则从 View
的构造函数调用 setBackground()
。在你的情况下,它在这里调用:
super(ctx, attrs);
如果要将背景设置为mRenderer
,可以在init
:
private void init(Context ctx) {
mRenderer = new MyRenderer(ctx);
setRenderer(mRenderer);
final Drawable background = getBackground();
if (background != null) {
mRenderer.setBackground(background);
}
}
并在 setBackground
中添加一个 null-check,因为在将某些值设置为 mRenderer
@Override
public void setBackground(Drawable background) {
if (mRenderer != null) {
mRenderer.setBackground(background);
}
}