программно добавляя SurfaceView к FrameLayout, который упорядочен по Z в ImageView

РЕДАКТИРОВАТЬ 2a: не стесняйтесь прыгать вниз для кратких вопросов.

Я могу нарисовать SurfaceView через xml. В моем случае я создаю электронную книгу, в которой на SurfaceViews будут работать разные анимации для каждой страницы книги.

У меня есть макет .xml, в котором FrameLayout называется @+id/animation_layout.

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    >
        <fi.harism.curl.CurlView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/curl"
        >
        </fi.harism.curl.CurlView>
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/animation_layout"
        />
        <include layout="@layout/narration" 
        />
    </RelativeLayout>

В зависимости от того, какая страница книги отображается, я хотел бы добавить другой экземпляр одного из классов в свой набор классов, которые расширяют SurfaceView.

Page01SurfaceView extends PageAniSurfaceView {
    //
    // code here includes onDraw() definition
    //
}

Page02SurfaceView extends PageAniSurfaceView {
    //
    // code here includes onDraw() definition
    //
}

PageAniSurfaceView в основном создает поток при его создании и запускает этот поток при создании его представления.

public class PageAniSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private final String TAG = this.getClass().getSimpleName();
private TutorialThread _thread;

public PageAniSurfaceView(Context context) {
    super(context);
    init();
}

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

public void setBackground(int bg_id)
{
    // adding the callback (this) to the surface holder to intercept events
    getHolder().addCallback(this);
    // make the PageAniSurfaceView focusable so it can handle events
    setFocusable(true);

}

protected void init()
{
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    _thread = new TutorialThread(getHolder(), this);
    _thread.setRunning(true);
    _thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    _thread.setRunning(false);
    while (retry) {
        try {
            _thread.join();
            retry = false;
        } catch (InterruptedException e) {
            // we will try it again and again...
        }
    }
}

protected void draw_bitmaps(Canvas canvas)
{
         // will be overridden by child classes
}

@Override
protected void onDraw(Canvas canvas) {
    if(this.getVisibility() == View.VISIBLE)
    {
        if(canvas != null)
        {
            draw_bitmaps(canvas);
        }
    }
}

public void update_bitmaps() 
{
         // will be overridden by child classes
}

public void elementStarted(PageElement _pageElement) {
    // Nothing in parent class
}

public void elementFinished(PageElement mElement) {
    // Nothing in parent class
}
}

У меня есть класс с именем PageDisplayer, который отслеживает, на какой странице мы находимся, и должен addView() указать конкретный класс SurfaceView, который мне нужно включить для этой страницы.

public void displayPage()
{
    page = sSystemRegistry.pageSystem.getCurrentPage();
    mBookReader.mAnimationLayout.removeAllViews();

    PageAniSurfaceView _ani = null;

    switch(page.index)
    {
    case 1:
        _ani = new Page01SurfaceView(mBookReader);
        break;
    case 2:
        _ani = new Page02SurfaceView(mBookReader);
        break;
    case 3:
        _ani = new Page03SurfaceView(mBookReader);
        break;

    }

    if(_ani != null)
    {
        _ani.setWillNotDraw(false);
                    // mBookReader.mAnimationLayout is a FrameLayout in my .xml
        mBookReader.mAnimationLayout.addView(_ani);
        mElementDisplayer.setElementListener(_ani);
    }
}

Через точки останова ИЛИ LogCat я могу сказать, что потоки работают и вызываются onDraws. Растровые изображения, определенные и отображаемые, например, в Page01SurfaceView, отрисовываются один раз, но не перерисовываются, когда update_bitmaps() изменяет координаты (x,y) растрового изображения.

Почему растровые изображения не рисуются при каждом вызове onDraw(Canvas)?

изменить: если в представлении есть анимация над растровыми изображениями, то отображаются растровые изображения в SurfaceView.

РЕДАКТИРОВАТЬ 2: Краткий вопрос:

Будет ли Z-порядок ImageView выше SurfaceView препятствовать тому, чтобы SurfaceView рисовал себя?

Должен ли я просто использовать Просмотр, а не SurfaceView? Я собираюсь попробовать это и сообщить.


person Thunder Rabbit    schedule 05.07.2011    source источник


Ответы (1)


Я просто использую View, а не SurfaceView.

Дайан Хэкборн сказала, что «поверхностные представления очень особенные и на самом деле не являются представлениями (поверхность — это отдельное окно, Z-упорядоченное с вашим собственным), их Z-упорядочение не соответствует вашим представлениям. Поверхностное представление — это большой, тяжелый объект; не предназначен для обработки SurfaceView как обычного представления таким образом».

https://groups.google.com/d/topic/android-developers/COffLpanlz0/discussion

person Thunder Rabbit    schedule 28.07.2011