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来实现这个效果,就像下面这位仁兄做的一样。

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