86 votes

La vue centrale Android dans FrameLayout ne fonctionne pas

J'ai un FrameLayout dans lequel je dispose de deux contrôles : - une vue personnalisée qui dessine une image et du texte dessus - une vue de texte avec un texte

Je veux centrer les deux dans le FrameLayout mais je n'y arrive pas. Le Texview est bien centré, mon cusom view reste sur le côté gauche, quand je le rends 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 juste un 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 votes

D'où vient votre vue personnalisée ? Vous êtes sûr de gérer les paramètres dans votre constructeur ?

0 votes

Y a-t-il une raison particulière pour laquelle vous devez utiliser un FrameLayout et le TextView doit-il être affiché au-dessus de la vue ?

1 votes

Oui, le FrameLayout ne te permet pas de faire ça. C'est vraiment juste pour contenir une seule vue. Si vous en ajoutez d'autres, il aura le comportement exact que vous mentionnez, il ajoute simplement des éléments dans une pile verticale en les épinglant en haut à gauche. developer.Android.com/reference/Android/widget/FrameLayout.html

407voto

userrp1519825 Points 4193

Nous pouvons aligner une vue au centre de l'écran FrameLayout en fixant 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;

Note : utiliser FrameLayout.LayoutParams pas les autres LayoutParams existants

115 votes

Cela devrait être la réponse acceptée. L'autre modifie la question au lieu d'y répondre.

0 votes

Ajout d'une image au centre du cadre layout.cap = new ImageView(CameraActivity.this) ; LayoutParams params2 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) ; params2.gravity=Gravity.CENTER ; cap.setLayoutParams(params2) ; cameraView.addView(cap) ;

9 votes

Maintenant, ça marche pour moi. Mon erreur était que j'avais importé le mauvais paquet. Après 4 heures, j'ai compris que le paquet réel à importer était Android.widget.FrameLayout.LayoutParams ;

44voto

Octavian Damiean Points 20620

Je suggérerais un RelativeLayout au lieu d'un FrameLayout.

En supposant que vous voulez que le TextView soit toujours en dessous de l'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 l'option visibility d'un élément à gone alors l'espace que cet élément consommerait disparaîtrait alors que lorsque vous utilisez invisible au lieu de préserver l'espace qu'il consommerait.

Si vous souhaitez que le TextView se trouve au-dessus de l'ImageView, il vous suffit de ne pas utiliser l'attribut android:layout_alignParentTop ou le régler sur false et sur le TextView, laissez de côté le android:layout_below="@id/imageview" attribut. Comme ceci.

<?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 recherchiez.

7voto

Rohit Singh Points 1934

Il suffit de suivre cet ordre

Vous pouvez centrer n'importe quel nombre d'enfants dans un FrameLayout .

<FrameLayout
    >
    <child1
        ....
        android:layout_gravity="center"
        .....
        />
    <Child2
        ....
        android:layout_gravity="center"
        />
</FrameLayout>

Donc la clé est

en ajoutant android:layout_gravity="center" dans les vues enfant.

Par exemple :

J'ai centré un CustomView et un TextView sur un 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 :

enter image description here

1voto

MN. Vala Points 89

Définir '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>

0voto

Herman Points 456

Suivant https://stackoverflow.com/a/13025031/962916 Cela fonctionne pour moi pour centrer un TabLayout dans un FrameLayout.

enter image description here

final TabLayout tabLayout = new TabLayout(this);
// Configure TabLayout...
final FrameLayout tabLayoutContainer = new FrameLayout(this);
tabLayoutContainer.setBackgroundColor(Color.RED);

final FrameLayout.LayoutParams tabLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                dpToPx(28));
final FrameLayout.LayoutParams containerLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                dpToPx(48));

tabLayoutParams.gravity = Gravity.CENTER;
tabLayoutContainer.setLayoutParams(containerLayoutParams);
tabLayoutContainer.addView(tabLayout, tabLayoutParams);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X