J'ai un FrameLayout dans lequel j'ai 2 contrôles: - une vue personnalisée qui dessine une image et du texte dessus - une textview avec un texte
Je veux centrer les deux dans FrameLayout mais je n'arrive pas à le faire. La Texview est parfaitement centrée, ma vue personnalisée reste du côté gauche lorsque je la rend 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>
Pour Mathias, je ne fais rien dans le constructeur, c'est 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();
}
}
Je suggérerais un RelativeLayout au lieu d'un FrameLayout.
En supposant que vous souhaitiez que le TextView soit toujours en dessous du ImageView, j'utiliserais la disposition suivante.
<?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>
Notez que si vous définissez la variable visibility
d'un élément sur gone
, l'espace que cet élément consommerait disparaîtra alors que lorsque vous utilisez invisible
, l'espace qu'il consommerait sera préservé.
Si vous voulez que le TextView soit au-dessus du ImageView, laissez simplement le Android:layout_alignParentTop
ou le définissez sur false
et sur le TextView, laissez l'attribut Android:layout_below="@id/imageview"
. Comme ça.
<?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>
J'espère que c'est ce que vous cherchiez.
Nous pouvons aligner une vue au centre de la FrameLayout
en définissant le layout_gravity
de la vue enfant.
En XML:
Android:layout_gravity="center"
En code Java:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
Remarque: utilisez FrameLayout.LayoutParams et non les autres LayoutParams existants.
Vous pouvez centrer n’importe quel nombre d’enfants dans une FrameLayout
.
<FrameLayout
>
<child1
....
Android:layout_gravity="center"
.....
/>
<Child2
....
Android:layout_gravity="center"
/>
</FrameLayout>
La clé ajoute donc Android:layout_gravity="center"
dans les vues enfant.
Par exemple:
J'ai centré un CustomView et une TextView
sur une FrameLayout
comme ceci
Code:
<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>
Résultat:
Pour centrer une vue dans Framelayout, quelques astuces sont disponibles. Le plus simple que j'ai utilisé pour ma Webview et ma barre de progression (très similaire à la disposition de vos deux objets), je viens d'ajouter Android:layout_gravity="center"
Voici un XML complet au cas où quelqu'un d'autre aurait besoin de faire la même chose
<?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>
Voici ma sortie
Définissez 'center_horizontal' et 'center_vertical' ou simplement 'center' de l'attribut layout_gravity du 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>