Android——實現等格子的類似W8系統瓷磚效果的佈局

在一些APP上我們經常看見這樣子的佈局:


實現的思路有兩種:

1 最普通的是直接在XML設置,利用LinearLayout嵌套LinearLayout,然後設置各個控件android:layout_weight屬性實現空間分割

2 利用網格視圖GridView


一、XML設置

效果圖:

源碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <Button
            android:background="@drawable/bg_border"
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="1" />

        <Button
            android:background="@drawable/bg_border"
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
             android:layout_weight="1"
            android:text="2" />

    </LinearLayout>

    <LinearLayout
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:background="@drawable/bg_border"
            android:id="@+id/button3"
             android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="3" />

        <Button
            android:background="@drawable/bg_border"
             android:layout_weight="1"
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="4" />

    </LinearLayout>

    <LinearLayout
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/button5"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/bg_border"
            android:text="5" />

        <Button
            android:background="@drawable/bg_border"
             android:layout_weight="1"
            android:id="@+id/button6"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="6" />

    </LinearLayout>

</LinearLayout>


注意點:
1邊框問題,在測試的時候發現,用Android自帶的按鈕樣式,發現有白色的邊框,一開始以爲是頁面的留白,無論怎麼設置,都無法去掉,後來想可能是按鈕樣式問題,將控件背景換成紅色背景+邊框之後之後,發現再也沒有出現白色邊框了,如果需要實現源圖的無縫連接,要重寫按鈕的UI顯示
2android:layout_weight屬性設置對於如何分配空間問題參考:http://mobile.51cto.com/abased-375428.htm PS:這個屬性只在LinearLayout裏有

二、網格視圖GridView

網格視圖本來的用途就是來顯示網格佈局的組件,在這裏我們需要額外的計算組件的高度,問題避免組件高度超出屏幕高度使得網格內容下滑,爲方便編程與實驗,app主題選用無標題欄的。
先貼效果圖:



源碼很簡單:貼出來
package com.example.tail;
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class qq extends Activity {
	private  int[] imageID ={R.drawable.icon1,R.drawable.icon2,R.drawable.icon3,R.drawable.icon4,R.drawable.icon5,R.drawable.icon6,R.drawable.icon7,R.drawable.icon8};
	private  String[] titles = {"今日看點","新浪微博","我的收藏","新聞頭條","科技頻道","汽車頻道","軍事頻道","新華炫文"};
	ArrayList<imageInfo> m;//封裝了保存圖像ID與文本標題的Item對象
    
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//加載GridView對象並獲取設備屏幕高度
		setContentView(R.layout.layout_gv);
	    DisplayMetrics dm = getResources().getDisplayMetrics();
	    final int ScreenHight = dm.heightPixels;
	    //實例化數據
	    m =imageInfo.get(imageID,titles);
		GridView g = (GridView)findViewById(R.id.gridView1);
		g.setAdapter(new BaseAdapter() {
			public View getView(int position, View convertView, ViewGroup parent) {
				//加載子選項界面並佈局
				LinearLayout item =(LinearLayout)LayoutInflater.from(qq.this).inflate(R.layout.grid_item, null);
				ImageView iv = (ImageView)item.findViewById(R.id.imageView1);
				TextView tv = (TextView)item.findViewById(R.id.textView1);
				
				iv.setBackgroundResource(m.get(position).imageid);
				tv.setText(m.get(position).title);
	
					item.setLayoutParams(new AbsListView.LayoutParams(
							android.view.ViewGroup.LayoutParams.MATCH_PARENT,
							ScreenHight/4));
				
				return item;
			}
			
			@Override
			public long getItemId(int position) {
				// TODO Auto-generated method stub
				return position;
			}
			
			@Override
			public Object getItem(int position) {
				// TODO Auto-generated method stub
				return position;
			}
			
			@Override
			public int getCount() {
				// TODO Auto-generated method stub
				return 8;
			}
		});
	}
	
}
可以看出,實際效果與我們所需的不同:我們是要實現不能滑動,完美填充屏幕的等格子布局,很明顯組件內容超出了屏幕最大高度。
首先第一想的是GridView的每個子項的高度是否真的是屏幕高度的1/4
在getView辦法中添加斷點測試34與45行,在Debug模式中發現作爲父容器的GridView的高度只有762,作爲GridView父容器的FrameLayout高度也是762,但是再上一級的父容器LinearLayout容器就有800了。然後我們再觀察GridView裏的mChlidren裏的每個Item組件的高度確實是200。所以很有可能我們得到的屏幕高度是手機固定的分辨率,包括可分配空間與不可分配空間(例如通知欄的高度也算進去了)。那麼很自然而然我們設每個組件的高度爲設備的高度的1/N必然會溢出。
我們的設想是這樣子,那麼就改一下代碼來實驗一下。
主要代碼:刪掉原先ScreenHight的語句,在getView()中添加下面一句
	int ScreenHight = g.getHeight()/4;
實驗結果:看起來更加順眼了,但是仍然存在上下滑動問題。雖然組件大小更加適合設備屏幕,但很顯然這不是主要問題。
打開手機的顯示佈局邊界功能:發現問題的所在:



問題所在於,整個GridView都被一個容器所包容,且與這容器有一定的邊距,所以會出現下滑現象。本來我們的GridView與屏幕完美切合,來一個有邊距的容器包容,就會破壞掉整個佈局。問題找到了,可是想不到辦法來解決,我還是先看看api文檔怎麼說,如果有哪位高手能知道問題所在,不煩賜教。

總體而言:使用GridView來編程,繁瑣問題又多,不如第一個辦法好,當然第一個辦法其實也很麻煩。不過我們也可以重寫自己的ViewGrop來實現這個效果,就像下面這位仁兄做的一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章