Introduction à cette section

FrameLayout (Frame Layout) peut être considéré comme le plus simple des six principaux layouts. Ce layout ouvre directement une zone vide à l'écran. Lorsque nous y ajoutons des contrôles, ils sont placés par défaut dans le coin supérieur gauche de cette zone. Cependant, cette méthode de disposition n'a aucune méthode de positionnement, donc ses scénarios d'application ne sont pas nombreux. La taille du frame layout est déterminée par le plus grand contrôle enfant parmi les contrôles. Si les contrôles ont la même taille, alors seul le composant le plus haut peut être vu en même temps ! Les contrôles ajoutés plus tard couvriront le précédent ! Bien que les contrôles soient placés par défaut dans le coin supérieur gauche, nous pouvons également spécifier d'autres positions via l'attribut layout_gravity. En plus de démontrer l'exemple le plus simple, cette section apporte également deux exemples amusants ; si cela vous intéresse, vous pouvez y jeter un œil !

1. Attributs courants

FrameLayout a très peu d'attributs, seulement deux, mais avant d'en parler, commençons par présenter une chose :

Image de premier plan : une image qui se trouve toujours au-dessus de la mise en page de cadre, directement face à l'utilisateur, c'est-à-dire une image qui ne sera pas recouverte.

Deux attributs :

  • android:foreground:*Définit l'image de premier plan du conteneur de mise en page de cadre
  • android:foregroundGravity:Définit la position où l'image de premier plan est affichée

2. Exemples de démonstration

1) L'exemple le plus simple

Capture d'écran du résultat d'exécution :

23622209

Le code d'implémentation est le suivant :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    xmlns:tools="http://schemas.android.com/tools"    
    android:id="@+id/FrameLayout1"    
    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    tools:context=".MainActivity"     
    android:foreground="@drawable/logo"    
    android:foregroundGravity="right|bottom">    
    
    <TextView    
        android:layout_width="200dp"    
        android:layout_height="200dp"    
        android:background="#FF6143" />    
    <TextView    
        android:layout_width="150dp"    
        android:layout_height="150dp"    
        android:background="#007FFE" />    
     <TextView    
        android:layout_width="100dp"    
        android:layout_height="100dp"    
        android:background="#FFFF00" />    
        
</FrameLayout>    

Analyse du code :Très simple. Trois TextView sont définis avec des tailles et des couleurs d'arrière-plan différentes, se recouvrant l'un l'autre dans l'ordre. Ensuite, dans le coin inférieur droit se trouve l'image de premier plan. Utilisez android:foreground="@drawable/logo" pour définir l'image de premier plan, et android:foregroundGravity="right|bottom" pour définir la position de l'image de premier plan dans le coin inférieur droit.

2) Jolie fille se déplaçant avec votre doigt

L'effet est le suivant :

18442553

Analyse du processus d'implémentation :

  • Étape 1 : Commencez par définir la mise en page main.xml comme un FrameLayout vide, et définissez une image d'arrière-plan pour celui-ci.
  • Étape 2 : Créez une classe de composant personnalisé MeziView qui hérite de la classe View, et initialisez les coordonnées initiales de la vue dans le constructeur.
  • Étape 3 : Redéfinissez la méthode onDraw() et instanciez une classe Paint vide.
  • Étape 4 : Appelez BitmapFactory.decodeResource() pour générer un objet bitmap.
  • Étape 5 : Appelez canvas.drawBitmap() pour dessiner l'objet bitmap de la fille.
  • Étape 6 : Vérifiez si l'image est recyclée ; sinon, forcez le recyclage de l'image.
  • Étape 7 : Dans le code Java principal, obtenez l'objet frame layout et instanciez une classe MeziView.
  • Étape 8 : Ajoutez un écouteur d'événement tactile à l'objet mezi instancié, redéfinissez la méthode onTouch, modifiez les coordonnées X,Y de mezi et appelez la méthode de redessin invalidate().
  • Étape 9 : Ajoutez l'objet mezi au frame layout.

Code de mise en page :main_activity.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    xmlns:tools="http://schemas.android.com/tools"    
    android:id="@+id/mylayout"    
    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    tools:context=".MainActivity"    
    android:background="@drawable/back" >    
</FrameLayout>    

PersonnaliséMeziView.java

package com.jay.example.framelayoutdemo2;  
  
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.graphics.Canvas;  
import android.graphics.Paint;  
import android.view.View;  
  
public class MeziView extends View {  
    //定义相关变量,依次是妹子显示位置的X,Y坐标  
    public float bitmapX;  
    public float bitmapY;  
    public MeziView(Context context) {  
        super(context);  
        //设置妹子的起始坐标  
        bitmapX = 0;  
        bitmapY = 200;  
    }  
 
    //重写View类的onDraw()方法  
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        //创建,并且实例化Paint的对象  
        Paint paint = new Paint();  
        //根据图片生成位图对象  
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.s_jump);  
        //绘制萌妹子  
        canvas.drawBitmap(bitmap, bitmapX, bitmapY,paint);  
        //判断图片是否回收,木有回收的话强制收回图片  
        if(bitmap.isRecycled())  
        {  
            bitmap.recycle();  
        }  
    } 
}  

MainActivity.java :

package com.jay.example.framelayoutdemo2;  
  
import android.os.Bundle;  
import android.view.MotionEvent;  
import android.view.View;  
import android.view.View.OnTouchListener;  
import android.widget.FrameLayout;  
import android.app.Activity;  
  
  
public class MainActivity extends Activity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        FrameLayout frame = (FrameLayout) findViewById(R.id.mylayout);  
        final MeziView mezi = new MeziView(MainActivity.this);  
        //为我们的萌妹子添加触摸事件监听器  
        mezi.setOnTouchListener(new OnTouchListener() {  
            @Override  
            public boolean onTouch(View view, MotionEvent event) {  
                //设置妹子显示的位置  
                mezi.bitmapX = event.getX() - 150;  
                mezi.bitmapY = event.getY() - 150;  
                //调用重绘方法  
                mezi.invalidate();  
                return true;  
            }  
        });  
        frame.addView(mezi);  
    }  
}  

Explication du code :Voir les étapes. C'est très simple : définissez une classe View personnalisée, redéfinissez la méthode de redessin, puis ajoutez-lui un événement tactile dans l'Activity. Dans l'événement tactile, redéfinissez la méthode onTouch pour obtenir le focus du clic. De plus, vous devez soustraire 150, sinon les coordonnées correspondent au coin supérieur gauche de la View personnalisée. Appelez ensuite la méthode de redessin invalidate(), et enfin ajoutez-la au frame layout !

Téléchargement du code :FrameLayoutDemo2.zip

3) Exécution de la jolie fille

L'effet est le suivant :

Processus de mise en œuvre :

  • Étape 1 : Définissez une mise en page FrameLayout vide et définissez la position de l’image d’avant-plan au centre.
  • Étape 2 : Dans l’Activity, récupérez la mise en page FrameLayout, créez un nouvel objet Handler, redéfinissez la méthode handlerMessage() et appelez la méthode de mise à jour de l’image.
  • Étape 3 : Définissez une méthode personnalisée move() et utilisez switch pour définir dynamiquement le bitmap affiché par l’image d’avant-plan.
  • Étape 4 : Dans la méthode onCreate(), créez un objet Timer, redéfinissez la méthode run et envoyez un message vide au handler toutes les 170 millisecondes.

Le code d'implémentation est le suivant :

Fichier de mise en page : main_activity.xml :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    xmlns:tools="http://schemas.android.com/tools"    
    android:id="@+id/myframe"    
    android:layout_width="wrap_content"    
    android:layout_height="wrap_content"     
    android:foregroundGravity="center">    
</FrameLayout>

MainActivity.java :

package com.jay.example.framelayoutdemo3;    
    
import java.util.Timer;    
import java.util.TimerTask;    
import android.os.Bundle;    
import android.os.Handler;    
import android.os.Message;    
import android.view.View;    
import android.view.View.OnClickListener;    
import android.widget.FrameLayout;    
import android.app.Activity;    
import android.graphics.drawable.Drawable;    
    
public class MainActivity extends Activity {    
    //初始化变量,帧布局    
    FrameLayout frame = null;    
    //自定义一个用于定时更新UI界面的handler类对象    
        Handler handler = new Handler()    
        {    
            int i = 0;    
            @Override    
            public void handleMessage(Message msg) {    
            //判断信息是否为本应用发出的    
                if(msg.what == 0x123)    
                {    
                    i++;    
                    move(i % 8 );    
                }    
                super.handleMessage(msg);    
             }    
        };          
            
    //定义走路时切换图片的方法    
    void move(int i)    
    {    
        Drawable a = getResources().getDrawable(R.drawable.s_1);    
        Drawable b = getResources().getDrawable(R.drawable.s_2);    
        Drawable c = getResources().getDrawable(R.drawable.s_3);    
        Drawable d = getResources().getDrawable(R.drawable.s_4);    
        Drawable e = getResources().getDrawable(R.drawable.s_5);    
        Drawable f = getResources().getDrawable(R.drawable.s_6);    
        Drawable g = getResources().getDrawable(R.drawable.s_7);    
        Drawable h = getResources().getDrawable(R.drawable.s_8);    
        //通过setForeground来设置前景图像    
        switch(i)    
        {    
            case 0:    
                frame.setForeground(a);    
                break;    
            case 1:    
                frame.setForeground(b);    
                break;    
            case 2:    
                frame.setForeground(c);    
                break;    
            case 3:    
                frame.setForeground(d);    
                break;    
            case 4:    
                frame.setForeground(e);    
                break;    
            case 5:    
                frame.setForeground(f);    
                break;    
            case 6:    
                frame.setForeground(g);    
                break;    
            case 7:    
                frame.setForeground(h);    
                break;    
        }    
    }    
        
    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);    
            
        frame = (FrameLayout) findViewById(R.id.myframe);    
        //定义一个定时器对象,定时发送信息给handler    
        new Timer().schedule(new TimerTask() {    
                
            @Override    
            public void run() {    
                //发送一条空信息来通知系统改变前景图片    
                handler.sendEmptyMessage(0x123);    
            }    
        }, 0,170);     
    }    
}    

Analyse du code :Le code est également très simple. Il définit un objet handler pour actualiser l’image d’avant-plan de la mise en page FrameLayout, et définit un Timer qui envoie des informations de temporisation toutes les 170 millisecondes, i++; move(i%8); c’est parce que nous utilisons 8 images comme matériaux d’animation !

Téléchargement du code :FrameLayoutDemo3.zip

Résumé de la section

Cette section présente FrameLayout (Frame Layout). Vous devez principalement maîtriser l’utilisation des attributs foreground et foregroundGravity. La mise en page FrameLayout est utilisée un peu plus que la précédente mise en page de tableau ! Si cela vous intéresse, vous pouvez écrire quelques petits exemples comme l’auteur et les essayer !