android佈局——FrameLayout(幀佈局)詳解

FrameLayout(幀佈局)

前言

作為android六大佈局中最為簡單的佈局之一,該佈局直接在屏幕上開辟出瞭一塊空白區域,

當我們往裡面添加組件的時候,所有的組件都會放置於這塊區域的左上角;

幀佈局的大小由子控件中最大的子控件決定,

如果都組件都一樣大的話,同一時刻就隻能能看到最上面的那個組件瞭!

當然我們也可以為組件添加layout_gravity屬性,從而制定組件的對其方式

幀佈局在遊戲開發方面用的比較多,等下後面會給大傢演示一下比較有意思的兩個實例

前景圖像:

永遠處於幀佈局最頂的,直接面對用戶的圖像,,就是不會被覆蓋的圖片

常用屬性:

android:foreground:設置該幀佈局容器的前景圖像

android:foregroundGravity:設置前景圖像顯示的位置

應用實例:

①最簡單的實例:

屬性很簡單,接著演示下FrameLayout的基本用法

真的很簡單,網上大部分的例子都是這個= =,

效果圖:

代碼如下:

vcD4KPHByZSBjbGFzcz0=”brush:java;”><frameLayout xmlns:android=”https://schemas.android.com/apk/res/android”
xmlns:tools=”https://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”>

</frameLayout>

代碼解釋:

如圖,我們設置瞭三個圖片塊,而這些圖片塊僅僅是三個設置瞭不同背景顏色的TextView

TextView都出現在瞭左上角,為瞭避免覆蓋,大小是依次遞減的

在外層FrameLayout中設置瞭前景圖像顯示的圖片,以及把它設置到瞭右下角

②跟隨手指移動的萌妹子

效果圖:

實現流程:

step 1:先將main.xml佈局設置為空白的FrameLayout,為其設置一個圖片背景

step 2:新建一個繼承View類的MeziView自定義組件類,在構造方法中初始化view的初始坐標

step 3:重寫onDraw()方法,實例化一個空的畫筆類Paint

step 4:調用BitmapFactory.decodeResource()生成位圖對象

step 5:調用canvas.drawBitmap()繪制妹子的位圖對象

step 6:判斷圖片上是否回收,否則強制回收圖片

step 7:在主Java代碼中獲取幀佈局對象,並且實例化一個MeziView類

step 8:會實例化的mezi對象添加一個觸摸事件的監聽器,重寫onTouch方法,改變mezi的X,Y坐標,調用invalidate()重繪方法

step 9: 將mezi對象添加到幀佈局中

詳細代碼:

佈局代碼:

<frameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://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>

自定義的MeziView類

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();
		}
		
	}
		
}

主Activity類:

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();
				mezi.bitmapY = event.getY();
				//調用重繪方法
				mezi.invalidate();
				return true;
			}
		});
		
		frame.addView(mezi);
		
	}
}

代碼解釋:

步驟寫的很詳細,代碼也不難,自己看看吧

就是自定義瞭一個View類,然後重寫瞭一下重繪方法,接著在主Activity中為它添加瞭一個觸摸事件

在觸摸事件中重寫onTouch方法獲得點擊坐標,調用invalidate()重繪方法;

最後添加到幀佈局中而已

代碼鏈接:

https://pan.baidu.com/s/1pJJfKgz

③跑動的萌妹子

效果圖:

實現流程:

step 1:定義一個空的FrameLayout佈局,將前景圖像的位置設置為中央位置

step 2:在Activity中獲取到該FrameLayout佈局,新建一個Handler對象,重寫handlerMessage()方法,調用圖像更新的方法

step 3:自定義一個move()方法,通過switch動態設置前景圖片顯示的位圖

step 4:在onCreate()方法中新建一個計時器對象Timer,重寫run方法,每隔170毫秒向handler發送空信息

代碼如下:

xml佈局代碼:

<frameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://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); 
	}
	
		

}

代碼解釋:

代碼也不是很發雜,就是定義一個handler對象來刷新幀佈局的前景圖像

用Timer對來定時發送信息

i++; move(i % 8 ); //這裡是因為有8個圖片作為動畫的素材

代碼鏈接:

https://pan.baidu.com/s/1c0vL8PE

總結:

以上就是FrameLayout的詳解,FrameLayout還是比較有趣的

幀動畫就是一個比較常見的例子

如有遺漏,讀者可以向我指出

O(∩_∩)O謝謝!

發佈留言