Android 与布局预览兼容的自定义视图初始化模式

Android 与布局预览兼容的自定义视图初始化模式,android,android-layout,android-studio,Android,Android Layout,Android Studio,我想知道是否有什么好的设计模式用于初始化自定义视图(例如传入模型/渲染器)。我特别感兴趣的是允许Android Studio布局预览工作(或类似工作)的模式 例如,以一个简单的游戏结构为例: layout.xml <LinearLayout> <com.package.GameSurface> </LinearLayout> 类似的东西会使Android studio布局预览崩溃,因为onDraw和onSizeChanged如果在没有init()的情况下

我想知道是否有什么好的设计模式用于初始化自定义视图(例如传入模型/渲染器)。我特别感兴趣的是允许Android Studio布局预览工作(或类似工作)的模式

例如,以一个简单的游戏结构为例:

layout.xml

<LinearLayout>
  <com.package.GameSurface>
</LinearLayout>
类似的东西会使Android studio布局预览崩溃,因为onDraw和onSizeChanged如果在没有
init()
的情况下调用,都会抛出空指针异常

是否有其他方法可以实现这一点?我脑子里闪过一些想法:

  • 在布局预览中具有要回退到的默认渲染器和模型。如果这是首选解决方案,是否有方法检测我的代码正在布局预览中运行
  • 可以选择通过某种XML属性选择渲染器,例如,
    custom:renderer=“@values/default\u renderer”
    ,然后为布局预览视图
    tools:renderer=“@values/preview\u renderer”
    指定一个。似乎有可能(见限制部分)。在某些情况下,如果无法在静态/预览上下文中轻松完成渲染器的实例化,这也可能不起作用
  • 也许有一种方法可以在布局预览中运行一些我忽略的设置代码
public class GameSurface extends View {

    int mComputedParam;

    Renderer mRenderer;
    GameState mGameState;

    public PlaySurface(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PlaySurface(Context context) {
        super(context);
    }

    // What are other ways of achieving this?
    public void init(GameState gameState, Renderer renderer) {
        mGameState = gameState;
        mRenderer = renderer;
    }

    @Override
    protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) {
        // Game state is used to calculate some layout/size/render information on the fly
        mComputedParam = (newWidth - getPaddingLeft() - getPaddingRight()) / mGameState.level();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // Render can be swapped out based on level or user settings, etc
        mRenderer.draw();
    }

}