以编程方式将 SurfaceView 添加到在 ImageView 下按 Z 顺序排列的 FrameLayout
编辑2a:随意跳到底部询问简洁的问题。
我可以通过xml绘制SurfaceView。就我而言,我正在创建一本电子书,该电子书将在书的每一页的 SurfaceView 上运行不同的动画。
我有一个 .xml
布局,其中有一个名为 @+id/animation_layout
的 FrameLayout
。
<?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:简洁问题:
在 SurfaceView
上方按 Z 顺序排列的 ImageView
是否会阻止 SurfaceView
自行绘制?
我应该使用 查看而不是 SurfaceView?我要尝试一下并报告回来。
EDIT 2a: feel free to jump to the bottom for succinct questions.
I can Draw a SurfaceView via xml. In my case, I am creating an e-book which will have different animations running on SurfaceViews for each page of the book.
I've got a .xml
layout that has a FrameLayout
called @+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>
Depending on which page of the book is being displayed, I would like to add a different instance of one of the classes in my set of classes which extend SurfaceView
.
Page01SurfaceView extends PageAniSurfaceView {
//
// code here includes onDraw() definition
//
}
Page02SurfaceView extends PageAniSurfaceView {
//
// code here includes onDraw() definition
//
}
PageAniSurfaceView basically creates a Thread when it's instantiated and kicks off that thread when its View is created.
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
}
}
I have a class called PageDisplayer
which keeps track of which page we're on, and should addView()
the specific SurfaceView class I need to include for that page.
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);
}
}
Via breakpoints OR LogCat, I can tell the Threads are running, and the onDraws are being called. The bitmaps defined and displayed in e.g., Page01SurfaceView are drawn once, but not redrawn when update_bitmaps() changes the (x,y) coordinates of the bitmap.
Why are the bitmaps not being drawn on each call to onDraw(Canvas)
?
edit: if there's an animation in a View above the bitmaps, then the bitmaps on the SurfaceView are displayed.
EDIT 2: Succinct Question:
Will an ImageView
Z-ordered above a SurfaceView
keep the SurfaceView
from drawing itself?
Should I just be using a View and not a SurfaceView
? I'm going to try that and report back.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我只是使用 View,而不是 SurfaceView。
Dianne Hackborn 说“表面视图非常特殊,而不是真正的视图(表面是一个与你自己的 Z 排序的单独窗口),它们的 Z 排序与你的视图不匹配。表面视图是一个又大又重的对象;你是无意以这种方式将 SurfaceView 视为常规视图。”
https://groups.google.com/d/topic/android-developers /COffLpanlz0/讨论
I'm just using a View, not a SurfaceView.
Dianne Hackborn said "surface views are very special and not really views (the surface is a separate window Z-ordered with your own), their Z-ordering does not match your views. A surface view is a big, heavy object; you are not intended to treat SurfaceView like a regular view in this way."
https://groups.google.com/d/topic/android-developers/COffLpanlz0/discussion