自定义一个简单菱形的布局
来源:互联网 发布:网络药品经营管理办法 编辑:程序博客网 时间:2024/05/29 10:06
最近在做项目的时候遇到这么一个情况,如图1,上面有9块相同的小块绿地,它的下面是一大块地,如图2,如果不考虑屏幕适配的问题,要想实现这个非常的容易,但是如果考虑到屏幕适配,自定义viewgroup是一个解决方案。
图1 图2
下面是布局代码:
MyViewFeildGroup就是我自己定的一个集成viewgroup的布局方式。id为iv_big_field的图片大小决定MyViewFeildGroup的大小(因为布局的高宽都是wrap_content)。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.swu.shen_pc.ninelayout.MainActivity"> <com.swu.shen_pc.ninelayout.nine_layout.MyViewFeildGroup android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content"> <!--下面的最大块地--> <ImageView android:id="@+id/iv_big_field" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/farm_pic_land" /> <!--下面9个imageview分别是9块小绿地--> <ImageView android:id="@+id/iv_farm_green_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> <ImageView android:id="@+id/iv_farm_green_9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/farm_pic_greenland" android:visibility="visible" /> </com.swu.shen_pc.ninelayout.nine_layout.MyViewFeildGroup></RelativeLayout>
下面是MyViewGroup的Java代码:
onMearure方法用第一块大地的高宽计算出MyViewGroup布局的高宽,然后onLayout方法一次计算出这1块大地和其他9块小地相对于父布局的位置。
package com.swu.shen_pc.ninelayout.nine_layout;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import com.swu.shen_pc.ninelayout.BuildConfig;/** * Created by shen on 2015/12/22. */public class MyViewFeildGroup extends ViewGroup { private int mLandHeight; private int mLandWidth; public MyViewFeildGroup(Context context, AttributeSet attributes) { super(context, attributes); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int cCount = getChildCount(); double cWidth = 0; double cHeight = 0; MarginLayoutParams cParams = null; /** * 遍历所有childView根据其宽和高,以及margin进行布局 */ for (int i = 0; i < cCount; i++) { View childView = getChildAt(i); cWidth = (1.0 / 3) * mLandWidth; cHeight = (1.0 / 3) * mLandHeight; double cl = 0.0, ct = 0.0, cr = 0.0, cb = 0.0; switch (i) { case 0: cl = 0.0; ct = 0.0; cWidth = mLandWidth; cHeight = mLandHeight; cr = cl + cWidth; cb = cHeight + ct; childView.layout((int) cl, (int) ct, (int) cr, (int) cb); continue; case 1: cl = (1.0 / 3) * mLandWidth; ct = 0.0; break; case 2: cl = (1.0 / 6) * mLandWidth; ct = (1.0 / 6) * mLandHeight; break; case 3: cl = 0.0; ct = (1.0 / 3) * mLandHeight; break; case 4: cl = (1.0 / 2) * mLandWidth; ct = (1.0 / 6) * mLandHeight; break; case 5: cl = (1.0 / 3) * mLandWidth; ct = (1.0 / 3) * mLandHeight; break; case 6: cl = (1.0 / 6) * mLandWidth; ct = (1.0 / 2) * mLandHeight; break; case 7: cl = (2.0 / 3) * mLandWidth; ct = (1.0 / 3) * mLandHeight; break; case 8: cl = (1.0 / 2) * mLandWidth; ct = (1.0 / 2) * mLandHeight; break; case 9: cl = (1.0 / 3) * mLandWidth; ct = (2.0 / 3) * mLandHeight; break; default: break; } cr = cl + cWidth; cb = cHeight + ct; childView.layout((int) cl, (int) ct, (int) cr, (int) cb); } } /** * 计算所有ChildView的宽度和高度,如果高宽都是wrap_content,然后根据第一个childView的计算结果,设置自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式 */ int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 计算出所有的childView的宽和高 measureChildren(widthMeasureSpec, heightMeasureSpec); /** * 记录如果是wrap_content是设置的宽和高 */ int width; int height; int cWidth; int cHeight; MarginLayoutParams cParams = null; /** * 根据第1个childView,也就是第一块大地计算的出的宽和高,以及设置的margin计算容器的宽和高,主要用于容器是warp_content时 */ View childView = getChildAt(0); cWidth = childView.getMeasuredWidth(); cHeight = childView.getMeasuredHeight(); mLandHeight = childView.getMeasuredHeight(); mLandWidth = childView.getMeasuredWidth(); cParams = (MarginLayoutParams) childView.getLayoutParams(); width = cWidth + cParams.leftMargin + cParams.rightMargin; height = cHeight + cParams.topMargin + cParams.bottomMargin; if (BuildConfig.DEBUG) Log.d("MyViewFeildGroup", "height:" + height); if (BuildConfig.DEBUG) Log.d("MyViewFeildGroup", "width:" + width); /** * 如果是wrap_content设置为我们计算的值 * 否则:直接设置为父容器计算的值 */ setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : width, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight : height); }}
好,到此为止自定义的MyViewFeildGroup就自定义完成了,在用eclipse或者Android studio预览布局的时候,可以选择多个分辨率的屏幕看看,当然其中还有很多细节没有处理,但是解决现在这个情况是绰绰有余了。
1 0
- 自定义一个简单菱形的布局
- 一个简单的collectionView自定义布局
- java简单的循环操作--打印一个菱形
- 一个简单的div布局
- 一个简单首页的布局
- 使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS 使用纯代码自定义UITableViewCell实现一个简单的微博界面布局
- 使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- Android 自定义一个简单而又实用的流式Tag标签布局
- 简单题_打印一个菱形
- 一个简单的自定义Collection
- 自定义一个简单的ScrollView
- 一个简单的自定义popupwindow
- 自定义一个简单的PopupWindow
- 一个简单的自定义TopBar
- 一个简单的自定义SwitchButton
- 1、cas4.0 单点登录 之 https证书
- 深刻理解Live555源码,掌握这把RTSP,RTP的瑞士军刀
- angularjs 与 springmvc 遇到的一些问题
- 算法导论 第22章 22.1-3
- 递归实现折半查找
- 自定义一个简单菱形的布局
- 个人总结面试题
- Oracle查询表所属用户
- 图像的视差匹配(Stereo Matching)
- 【金融手册】什么是本票、汇票、支票、银行承兑汇票、系统性、非系统性风险、巴塞尔协议、QDII...
- iOS 谓词
- 最短路2
- JDK5新特性之可变参数
- Mac下MySQL卸载方法