Android——实现等格子的类似W8系统瓷砖效果的布局

来源:互联网 发布:淘宝怎么看天猫积分 编辑:程序博客网 时间:2024/04/28 16:45

在一些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;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 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来实现这个效果,就像下面这位仁兄做的一样。
http://www.cnblogs.com/Jaylong/p/viewgroup.html

0 0