Vista do Android Center em Framelayout não funciona
Pergunta
Eu tenho um Framelayout no qual tenho 2 controles: - Uma visualização personalizada que desenha uma imagem e algum texto nela - uma visão de texto com um texto
Quero centralizar os dois no Framelayout, mas não consigo fazer isso. O Texview está bem centrado, minha vista Cusom permanece no lado esquerdo, quando eu a torto visível.
<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, eu não faço nada no construtor, é apenas simples
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();
}
}
Solução
Eu sugeriria uma relatividade em vez de um Framelayout.
Supondo que você queira ter o TextView sempre abaixo do ImageView que eu usaria o seguinte layout.
<?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>
Observe que se você definir o visibility
de um elemento para gone
Então o espaço em que o elemento consumiria se foi enquanto quando você usa invisible
Em vez disso, o espaço consumido será preservado.
Se você quiser ter o TextView na parte superior do ImageView, basta deixar de fora o android:layout_alignParentTop
ou defina -o para false
E na visão de texto deixa de fora o android:layout_below="@id/imageview"
atributo. Assim.
<?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 seja isso que você estava procurando.
Outras dicas
Podemos alinhar uma visão no centro do FrameLayout
Configurando o layout_gravity
da visão da criança.
Em xml:
android:layout_gravity="center"
No código Java:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
Nota: Use FrameLayout.LayoutParams
não os outros existentes LayoutParams
Definir 'Center_horizontal' e 'Center_vertical' ou apenas 'centro' do atributo layout_gravity do widget
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MovieActivity"
android:id="@+id/mainContainerMovie"
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#3a3f51b5"
/>
<ProgressBar
android:id="@+id/movieprogressbar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" />
</FrameLayout>
Basta seguir este pedido
Você pode centralizar qualquer número de crianças em um FrameLayout
.
<FrameLayout
>
<child1
....
android:layout_gravity="center"
.....
/>
<Child2
....
android:layout_gravity="center"
/>
</FrameLayout>
Então a chave é
adicionando
android:layout_gravity="center"
nas visualizações da criança.
Por exemplo:
Eu centralizei um Visualização personalizada e a TextView com um FrameLayout
assim
Código:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<com.airbnb.lottie.LottieAnimationView
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_gravity="center"
app:lottie_fileName="red_scan.json"
app:lottie_autoPlay="true"
app:lottie_loop="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#ffffff"
android:textSize="10dp"
android:textStyle="bold"
android:padding="10dp"
android:text="Networks Available: 1\n click to see all"
android:gravity="center" />
</FrameLayout>
Resultado:
Para centralizar uma vista no Framelayout, existem alguns truques disponíveis. O mais simples que usei para o meu WebView e ProgressBar (muito semelhante ao seu layout de dois objetos), acabei de adicionar android:layout_gravity="center"
Aqui está o XML completo, caso alguém precise da mesma coisa para fazer
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WebviewPDFActivity"
android:layout_gravity="center"
>
<WebView
android:id="@+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ProgressBar
android:id="@+id/progress_circular"
android:layout_width="250dp"
android:layout_height="250dp"
android:visibility="visible"
android:layout_gravity="center"
/>
</FrameLayout>
Aqui está minha saída