Estoy dibujando algunos gráficos y me gustaría agregarle un par de botones. Pero con la vista de superficie, ¿cómo agregamos estos botones programáticamente?Android: Cómo agregar un botón en la vista de superficie
Respuesta
Encierre su surfaceView con un FrameLayout en su diseño xml. A continuación, agregue sus botones al mismo FrameLayout. Asegúrate de que estén colocados debajo de la vista de la superficie para que se dibujen encima de ella. (Podría ser una buena idea para unirlos en otra disposición y añadir que a la FrameLayout.)
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView android:id="@+id/surfaceView1" android:layout_width="wrap_content" android:layout_height="wrap_content"></SurfaceView>
<LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>
</FrameLayout>
Muchas gracias Androidica ..
Su xml me ha ayudado a entender la siguiente solución programáticamente sin utilizar ningún xml ..
public class LudoActivity extends Activity implements OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
FrameLayout game = new FrameLayout(this);
GameView gameView = new GameView (this);
LinearLayout gameWidgets = new LinearLayout (this);
Button endGameButton = new Button(this);
TextView myText = new TextView(this);
endGameButton.setWidth(300);
endGameButton.setText("Start Game");
myText.setText("rIZ..i");
gameWidgets.addView(myText);
gameWidgets.addView(endGameButton);
game.addView(gameView);
game.addView(gameWidgets);
setContentView(game);
endGameButton.setOnClickListener(this);
}
public void onClick(View v) {
Intent intent = new Intent(this, LudoActivity.class);
startActivity(intent);
// re-starts this activity from game-view. add this.finish(); to remove from stack
}
}
mientras GameView es;
public class GameView extends SurfaceView {
public GameView(Context context) {
super(context);
/*
* your code
*/
}
}
Muchas gracias por esta versión de código, el XML publicado en la otra respuesta me confundió. –
es mi placer ... eres bienvenido –
Podemos usar el diseño de marco para el dibujo de la vista de superficie muy fácilmente. como esta actividad
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="fill_parent"
android:layout_height="430dp"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center_horizontal"
android:layout_gravity="bottom"
android:background="#c2300f">
<Button
android:id="@+id/buttonColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Color" />
</LinearLayout>
</LinearLayout>
Y principal es
package com.example.surfacetuto;
import android.app.Activity;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
DrawingSurface ds;
FrameLayout frm;
Button btnC;
int color=0xfff00000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ds=new DrawingSurface(this);
setContentView(R.layout.activity_main);
frm=(FrameLayout)findViewById(R.id.frameLayout);
frm.addView(ds);
btnC=(Button)findViewById(R.id.buttonColor);
btnC.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.buttonColor:
Toast.makeText(getApplicationContext(), "Color", 2).show();
ds.colorNew();
break;
default:
break;
}
}
}
Y la clase de dibujo de la superficie es
package com.example.surfacetuto;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
Canvas cacheCanvas;
Bitmap backBuffer;
int width, height, clientHeight;
Paint paint;
Context context;
SurfaceHolder mHolder;
public DrawingSurface(Context context) {
super(context);
this.context = context;
init();
}
public DrawingSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
private void init() {
mHolder = getHolder();
mHolder.addCallback(this);
}
int lastX, lastY, currX, currY;
boolean isDeleting;
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
int action = event.getAction();
switch(action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getX();
lastY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
if(isDeleting) break;
currX = (int) event.getX();
currY = (int) event.getY();
cacheCanvas.drawLine(lastX, lastY, currX, currY, paint);
lastX = currX;
lastY = currY;
break;
case MotionEvent.ACTION_UP:
if(isDeleting) isDeleting = false;
break;
case MotionEvent.ACTION_POINTER_DOWN:
cacheCanvas.drawColor(Color.WHITE);
isDeleting = true;
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
draw();
return true;
}
protected void draw() {
if(clientHeight==0) {
clientHeight = getClientHeight();
height = clientHeight;
backBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
cacheCanvas.setBitmap(backBuffer);
cacheCanvas.drawColor(Color.WHITE);
}
Canvas canvas = null;
try{
canvas = mHolder.lockCanvas(null);
canvas.drawBitmap(backBuffer, 0,0, paint);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(mHolder!=null) mHolder.unlockCanvasAndPost(canvas);
}
}
private int getClientHeight() {
Rect rect= new Rect();
Window window = ((Activity)context).getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight= rect.top;
int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;
return ((Activity)context).getWindowManager().getDefaultDisplay().
getHeight() - statusBarHeight - titleBarHeight;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
width = getWidth();
height = getHeight();
cacheCanvas = new Canvas();
backBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
cacheCanvas.setBitmap(backBuffer);
cacheCanvas.drawColor(Color.WHITE);
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
draw();
}
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...
}
}
}
public void colorNew() {
// TODO Auto-generated method stub
paint.setColor(Color.GRAY);
}
}
Haga su propio botón:
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
public class GButton
{
public Matrix btn_matrix = new Matrix();
public RectF btn_rect;
float width;
float height;
Bitmap bg;
public GButton(float width, float height, Bitmap bg)
{
this.width = width;
this.height = height;
this.bg = bg;
btn_rect = new RectF(0, 0, width, height);
}
public void setPosition(float x, float y)
{
btn_matrix.setTranslate(x, y);
btn_matrix.mapRect(btn_rect);
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(bg, btn_matrix, null);
}
}
en caso de contacto:
float x = ev.getX();
float y = ev.getY();
if (my_button.btn_rect.contains(x, y))
{
// handle on touch here
}
alternativamente, aún mejor, si quieres también girar el botón no será ejes alineados, a continuación, utilizar la matriz invertida, en lugar de mapRect mapa los puntos de contacto con x, y:
float pts[] = {x, y};
my_button.invert_matrix.mapPoints(pts);
if (my_button.btn_rect.contains(pts[0], pts[1])
{
// handle on touch here
}
gracias por tu código, espero que me ayude. –
Gracias, ¡me funciona! –
Me gustaría ver una publicación en algún lugar que compare las ventajas de hacer los propios botones de esta manera para una vista de superficie versus usar el objeto de botón del widget de botón como en la respuesta de gruemeen4. Recientemente cambié mis propios botones personalizados en mi código de juego a objetos Button, y parece que no funciona tan bien para los clics. – Androidcoder
- 1. Vista de superficie de la cámara Android
- 2. lienzo transparente de Android (vista de superficie)
- 3. ¿Cómo agregar un botón en Android?
- 4. ¿Cómo agregar un botón hecho sobre la vista de selección?
- 5. Cómo sobrescribir una vista personalizada (vista de superficie)
- 6. ¿Cómo guardar la imagen junto con la vista de superficie en Android?
- 7. ¿Cómo agregar vista superpuesta sobre otra vista en android?
- 8. Cómo configurar el tamaño de la vista de superficie personalizada
- 9. ¿Cómo agregar un control de botón a una vista xml de Android en tiempo de ejecución?
- 10. Android: hacer cambios en la vista principal de un botón
- 11. ¿Cómo agregar el botón compartir en android?
- 12. cómo cambiar la cámara Android al retrato en la vista de superficie?
- 13. cómo pausar y reanudar un subproceso de vista de superficie
- 14. Agregar un botón estacionario Overtop de una vista de mapa
- 15. Cómo agregar encabezado a la vista de lista En Android
- 16. Agregar un botón debajo de una vista de lista en android
- 17. ¿Cómo agregar el botón dinámico en otra vista?
- 18. Superposición de un diseño de Android en una vista de superficie
- 19. Botón de AirPlay en la vista personalizada
- 20. Añadir botón en la costumbre Vista en Android
- 21. Cómo agregar un estado de botón personalizado
- 22. Cómo habilitar la retroalimentación háptica en la vista de botón
- 23. Android. Cómo visualizar el video en la superficie (OpenGL)
- 24. Android: ¿Cómo inicializar MediaRecorder sin una superficie válida para la vista previa del video?
- 25. ¿Agregar vista a un fragmento dinámicamente en Android?
- 26. Agregar diseño como una vista en Android
- 27. Cómo puedo agregar el botón en MapView android
- 28. Cómo agregar un botón Eliminar a la forma generada django.forms?
- 29. ¿Cómo agregar una imagen para el botón en Android?
- 30. Agregar animación a una Vista de lista en Android
He creado la superficieView programáticamente, pero cómo vincularla con la de XML. – m4n07
estoy usando este xml para mi actividad, en la cual desea inicializar la vista de superficie cuando el usuario toque en la vista de la imagen que se personaliza TouchImageView con zoom y pellizcar la funcionalidad de ImageView. Lo que trato de hacer es: (1) muestra la imagen de los servicios web, que he hecho con AQuery. (2) cuando el usuario selecciona la opción EDITAR de los CAB, habilita la vista de superficie con un texto editable que se puede arrastrar sobre la imagen. @androidika me puedes ayudar con esto. –