Android 如何初始化依赖于视图的内容’;s属性

Android 如何初始化依赖于视图的内容’;s属性,android,android-layout,glsurfaceview,Android,Android Layout,Glsurfaceview,假设我有这个类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) { mRend

假设我有这个类
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
中调用,在
MyView
中调用
init
之前,因此
mrender
尚未初始化

这看起来像是一个陷阱,因为如果没有视图的初始化,就无法设置视图的属性,而初始化是在属性设置之后发生的

这是布局图:

<?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尚未初始化。有很多工作要做。 这个链接可能会有所帮助


你是对的<如果分析了
android:background
属性,则会从
视图的构造函数调用code>setBackground()
。在您的案例中,它在这里调用:

super(ctx, attrs);
如果要将背景设置为
mrender
,可以在
init
中执行:

private void init(Context ctx) {
    mRenderer = new MyRenderer(ctx);
    setRenderer(mRenderer);
    final Drawable background = getBackground();
    if (background != null) {
        mRenderer.setBackground(background);
    }
}
并在
setBackground
中添加一个空检查,因为在将某个值设置为
mrender

@Override
public void setBackground(Drawable background) {
    if (mRenderer != null) {
        mRenderer.setBackground(background);
    }
}

你真的运行过这个代码吗?我假设视图
MyView
是布局XML
R.layout.my_布局的一部分。在这种情况下,
setContentView
将导致调用
MyView
上的构造函数。总之,
setBackground
是一个实例方法,在初始化渲染器之前(您在构造函数中初始化渲染器),它无法在代码流中调用@Dibzmania我在
MyView
中注释了
setBackground
,或者调用超级类的
setBackground
方法。对于前者,视图将具有黑色背景。对于后者,只有超类(我猜)渲染背景,而不是我的几何体,即使渲染器的
onDrawFrame
方法中存在所有绘制调用。请尝试在构造函数或init方法中调用
setZOrderOnTop(true)
。然后取消注释你的
setBackground
方法,看看它是否正确works@Dibzmania
setZOrderOnTop
将隐藏UI界面,它是
RelativeLayout
MyView
顶部的一些可绘制内容。在
my_view
膨胀后,我尝试从XML布局而不是活动的
init
方法设置背景图像之前,一切都正常。你能发布布局文件吗?