2010-10-29 13 views
53

Tengo un FrameLayout en el que tengo 2 controles: - una vista personalizada que dibuja una imagen y un texto sobre ella - un TextView con un textovista de centro de Android en FrameLayout no funciona

quiero centrar ambos en FrameLayout, pero no puedo hacerlo. El Texview está centrado muy bien, mi vista de cusomía permanece en el lado izquierdo, cuando lo hago visible.

<FrameLayout android:id="@+id/CompassMap" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:gravity="center"> 

      <view class="com.MyView" 
     android:id="@+id/myView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical|center_horizontal" 
     android:visibility="gone"/> 

       <TextView android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical|center_horizontal" 
     android:text="CENTERED" /> 
</FrameLayout> 

Para Mathias, que no hacen nada en el constructor, es sólo simple

public class MyMapView extends View { 

private int xPos = 0; 
private int yPos = 0; 
private Bitmap trackMap; 

private Matrix backgroundMatrix; 
private Paint backgroundPaint; 

private Bitmap position; 
private Matrix positionMatrix; 
private Paint positionPaint; 

public MyMapView(Context context) { 
    super(context); 
    init(context, null); 
} 

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

public MyMapView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context, attrs); 
} 

private void init(final Context context, AttributeSet attrs) { 

backgroundMatrix = new Matrix(); 
backgroundPaint = new Paint(); 
backgroundPaint.setFilterBitmap(true); 

position = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position); 
positionMatrix = new Matrix(); 

positionPaint = new Paint(); 
positionPaint.setFilterBitmap(true); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    int width = getMeasuredWidth(); 
    int height = getMeasuredHeight(); 

    if (trackMap!=null) 
    { 
     Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true); 
     canvas.drawBitmap(resizedBitmap, backgroundMatrix, backgroundPaint); 

    } 

     canvas.save(Canvas.MATRIX_SAVE_FLAG); 
     canvas.translate(xPos-position.getWidth()/2, yPos-position.getHeight()/2); 
     canvas.drawBitmap(position, positionMatrix, positionPaint); 

     canvas.restore(); 
} 

    public void updatePosition(int xpos, int ypos, Bitmap trackImage) 
    { 
     xPos=xpos; 
     yPos=ypos; 
     trackMap = trackImage; 
     invalidate(); 
    } 
} 
+1

¿De dónde es la extensión de su vista personalizada? ¿Seguro que está manejando los parámetros en su constructor? –

+0

¿Hay alguna razón especial por la que deba usar un FrameLayout y el TextView se muestre en la parte superior de la Vista? –

+1

Sí, el FrameLayout no te dejará hacer eso. Es realmente solo para mantener una vista única. Si agrega más a eso, tendrá el comportamiento exacto que está mencionando, simplemente agrega elementos en una pila vertical al anclar en la esquina superior izquierda. http://developer.android.com/reference/android/widget/FrameLayout.html – plainjimbo

Respuesta

29

me gustaría sugerir un RelativeLayout en lugar de un FrameLayout.

Suponiendo que desea tener TextView siempre debajo de ImageView, usaría el siguiente diseño.

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 
    <ImageView 
     android:id="@+id/imageview" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_centerInParent="true" 
     android:src="@drawable/icon" 
     android:visibility="visible"/> 
    <TextView 
     android:id="@+id/textview" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:layout_below="@id/imageview" 
     android:gravity="center" 
     android:text="@string/hello"/> 
</RelativeLayout> 

Tenga en cuenta que si se establece la visibility de un elemento a gone entonces el espacio que consumiría elemento se ha ido mientras que cuando se utiliza en lugar invisible el espacio que sería consumir será preservado.

Si usted quiere tener la TextView en la parte superior de la ImageView entonces simplemente dejar de lado el android:layout_alignParentTop o se establece en false y en la Vista de Texto dejar de lado el atributo android:layout_below="@id/imageview". Me gusta esto.

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 
    <ImageView 
     android:id="@+id/imageview" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="false" 
     android:layout_centerInParent="true" 
     android:src="@drawable/icon" 
     android:visibility="visible"/> 
    <TextView 
     android:id="@+id/textview" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:gravity="center" 
     android:text="@string/hello"/> 
</RelativeLayout> 

Espero que esto sea lo que estaba buscando.

+0

Tu explicación se ve muy bien y debería funcionar en mi caso, pero no es así. En mi RelativeLayout tengo más de lo que dije: 2 vistas personalizadas, LinearLayout, Button y TextView. Lo curioso es que todo funciona, excepto mi vista personalizada. La otra vista personalizada no se ve influenciada como atributos fill_parent. Pero, estoy tratando de ver si no me perdí algo. Gracias. – Alin

+0

¿Cuál es el propósito de su vista personalizada? –

+0

Agregué el código completo de la vista personalizada en la pregunta. Básicamente dibuja una imagen grande como fondo y una más pequeña en la posición x, y. – Alin

260

Podemos alinear una vista en el centro de la FrameLayout estableciendo el layout_gravity del niño, vista por

en XML:

layout_gravity = "center" 

(o)

en JAVA:

LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
lp.gravity = Gravity.CENTER; 

en su código.

+74

Esta debería ser la respuesta aceptada. El otro cambia la pregunta en lugar de responderla. – Muz

+0

Y esta solución no funcionó para mí. Agregar Imageview en el centro de Frame layout.cap = new ImageView (CameraActivity.this); \t \t LayoutParams params2 = new LayoutParams (LayoutParams.WRAP_CONTENT, \t \t \t \t LayoutParams.WRAP_CONTENT); \t \t params2.gravity = Gravity.CENTER; \t \t cap.setLayoutParams (params2); \t \t cameraView.addView (cap); –

+5

Ahora funcionó para mí. Mi error fue que me importaron el paquete equivocado. Después de 4 horas, recibí el error que el paquete real debería importar es android.widget.FrameLayout.LayoutParams; –

Cuestiones relacionadas