it-swarm.com.ru

SurfaceView в макете

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

У меня есть линейный макет, который установлен по горизонтали. Он содержит ImageView, затем вертикальный линейный макет и, наконец, еще один ImageView. В вертикальной линейной компоновке есть три важных вещи: еще один ImageView вверху, расширенный SurfaceView (называемый MagnetView) и ImageView внизу.

Вот XML:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="horizontal" >

 <!-- Left Magnetrak -->

 <ImageView
    Android:layout_width="wrap_content"
    Android:layout_height="fill_parent"
    Android:src="@drawable/vectorparts_01"
    Android:adjustViewBounds="true" />

<!-- Middle Linear Layout -->        
<LinearLayout 
    Android:layout_width="0dip"
    Android:layout_height="fill_parent"
    Android:orientation="vertical"
    Android:layout_weight="1">

    <!-- Top Bar with Lifes and Score counter -->
    <RelativeLayout
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:adjustViewBounds="true">

    <ImageView
    Android:adjustViewBounds="true"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:src="@drawable/vectorparts_22"/>

    <!-- Score counter -->
    <TextView
    Android:id="@+id/myImageViewText"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_alignParentRight="true"
    Android:layout_marginRight="10dp"
    Android:layout_marginTop="5dp"
    Android:gravity="center"
    Android:text="000000000000"
    Android:textColor="#000000" />

    <!-- Life1 -->
     <ImageView
        Android:id = "@+id/life1"
        Android:adjustViewBounds="true"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:src="@drawable/vectorparts_13" 
        Android:layout_alignParentLeft="true"
        Android:layout_marginLeft="5dp"
        Android:layout_marginTop="1dp"
        Android:gravity="center" />

     <!-- Life2 -->
     <ImageView
        Android:id = "@+id/life2"
        Android:adjustViewBounds="true"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:src="@drawable/vectorparts_13" 
        Android:layout_toRightOf="@id/life1"
        Android:layout_marginTop="1dp"
        Android:layout_marginLeft="1dp"
        Android:gravity="center" />

     <!-- Life3 -->
     <ImageView
        Android:id = "@+id/life3"
        Android:adjustViewBounds="true"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:src="@drawable/vectorparts_13" 
        Android:layout_toRightOf="@id/life2"
        Android:layout_marginTop="1dp"
        Android:layout_marginLeft="1dp"
        Android:gravity="center" />

    </RelativeLayout>

    <!-- SurfaceView -->
    <LinearLayout
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:id="@+id/middlesurface">

    </LinearLayout>

     <!-- Bottom Bar -->   
    <RelativeLayout
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:adjustViewBounds="true"> 

    <ImageView
    Android:adjustViewBounds="true"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:src="@drawable/vectorparts_02"/>


    </RelativeLayout>


</LinearLayout>

<!-- Right Magnetrak -->
   <ImageView
Android:layout_width="wrap_content"
Android:layout_height="fill_parent"
Android:src="@drawable/vectorparts_01"
Android:adjustViewBounds="true" />

По сути, я хочу, чтобы MagnetView показывал (или пробивал дыру), где я поместил его в макет. Но это не отображается. Фактически, единственный раз, когда мой SurfaceView отображает, это когда я явно устанавливаю setContentView () для активности в SurfaceView, отменяя все остальное.

Вот собственно Активность:

public class Magnetraks extends Activity {

MagnetView midSurf;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    midSurf = new MagnetView(this);
    LinearLayout midLL = new LinearLayout(this);

    midLL.findViewById(R.id.middlesurface);
    midLL.addView(midSurf);

    setContentView(R.layout.main);

    //Debugging purposes: run to see if middleSurface view is showing up when on its own.
    //setContentView(midSurf);


}

@Override
protected void onResume() {
 // TODO Auto-generated method stub
 super.onResume();
 midSurf.resume();
}

@Override
protected void onPause() {
 // TODO Auto-generated method stub
 super.onPause();
 midSurf.pause();
}

Должен ли я разместить SurfaceView в верхней части моего макета XML? Есть ли еще атрибуты, которые я должен установить? Могу ли я просто наложить SurfaceView поверх всего остального, сделать его полупрозрачным и нарисовать то, что мне нужно? Любая помощь будет принята с благодарностью, так как я не могу понять, как работают SurfaceViews. Кажется, они не входят в мою иерархию View, но затем документация говорит мне, что они совершенно разные.

Спасибо.

РЕДАКТИРОВАТЬ 17.04.2012

Чтобы предложить немного больше информации: мой xml UI Designer показывает большую коробку в середине для моего расширенного класса SurfaceView, который называется MagnetView. Я выделил это красным. (Stackoverflow пока не позволяет мне публиковать изображения)

Представление конструктора пользовательского интерфейса (http://24.media.tumblr.com/tumblr_m2mmqvBNwW1qcreoco1_500.jpg) http://24.media.tumblr.com/tumblr_m2mmqvBNwW1qcreoco1_500.jpg

Вот класс MagnetView (SurfaceView):

import Android.content.Context;
import Android.graphics.Canvas;
import Android.graphics.PixelFormat;
import Android.view.SurfaceHolder;
import Android.view.SurfaceView;

public class MagnetView extends SurfaceView implements Runnable, SurfaceHolder.Callback{
Thread mThread;
SurfaceHolder mSurfaceHolder;
volatile boolean running = false;

//Creates new surface view as well as a new surfaceholder, which allows access to the surface
public MagnetView (Context context){
    super(context);

    mSurfaceHolder = getHolder();
            mSurfaceHolder.addCallback(this);
    //this.setZOrderOnTop(true);
    //getHolder().setFormat(PixelFormat.TRANSLUCENT);


}

public void resume(){
    running = true;
    mThread = new Thread(this);
    mThread.start();
}

public void pause(){
       boolean retry = true;
       running = false;
       while(retry){
        try {
         mThread.join();
         retry = false;
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       }
}

@Override
public void run() {
  // TODO Auto-generated method stub
    while(running){
        if(mSurfaceHolder.getSurface().isValid()){
            Canvas canvas = mSurfaceHolder.lockCanvas();
            //... actual drawing on canvas

            canvas.drawARGB(100, 255, 255, 80);

            mSurfaceHolder.unlockCanvasAndPost(canvas);
        }
    }
}


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    this.resume();

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub

}

}
8
akappel

Я просто записываю изменения.

  1. Замените вид поверхности в xml на LinearLayout.

        <LinearLayout 
           Android:id="@+id/middleSurface"
           Android:layout_width="wrap_content"
           Android:layout_height="wrap_content"
        />
    
  2. Получить экземпляр линейного макета

    LinearLayout surface = (LinearLayout) findViewById (R.id.surface);

  3. Добавить экземпляр вида поверхности в LinearLayout

    surface.addView (новый MagnetView (это));

2,3 шага должны быть выполнены после setContentView (R.layout.main);

15
Chaitanya

Вы установили фон SurfaceView? Я обнаружил, что если вы установите фон SurfaceView, он не будет отображать то, что вы рисуете во вторичном потоке.

0
PyChen

Если я не ошибаюсь, ваш запрос воспринимается так: вы хотите, чтобы что-то отображалось/отображалось поверх представления поверхности вместе с другими элементами представления, как вы упомянули в xml.

Если вам нужен вид сверху поверхности, вам нужно расширить его (AFAIK другого пути нет). Затем вам нужно переопределить метод onDraw (), чтобы отобразить все, что вы хотите, на виде поверхности. Вам также нужно получить объект SurfaceHolder, который получает холст.

Вот хорошая ссылка, показывающая вид изображения поверх поверхности: http://www.droidnova.com/playing-with-graphics-in-Android-part-ii,160.html

0
Chaitanya

Вы можете попробовать другой способ, переместить setContentView(R.layout.main); после super.onCreate(savedInstanceState);

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
midSurf = new MagnetView(this);
LinearLayout midLL = new LinearLayout(this);

midLL.findViewById(R.id.middlesurface);
midLL.addView(midSurf);
0
Alv_quena

Я хотел бы изучить макет в конструкторе пользовательского интерфейса Eclipse, чтобы увидеть, все ли размещено так, как вы хотите. Поверхностные виды - это просто обычные виды макета.

0
Alexander Kulyakhtin
  1. Удалите вид поверхности из xml и поместите линейное расположение вместо этого и свяжите с ним идентификатор.
  2. Получить экземпляр linearlayout.
  3. добавьте дочернее представление, то есть, магнитное представление в этом случае к линейному расположению, используя

    addView ()

Это решило проблему.

0
Chaitanya