关于如果自己定义安卓的布局界面的初学研究
来源:互联网 发布:sql timestampdiff 编辑:程序博客网 时间:2024/06/05 14:13
之后苦苦思索了半天,才算是略有体会。
主要的问题在于:在我看的开源代码里面,作者自己定义了一个Layout,而未曾使用系统自带的如LinearLayout的页面布局。
这对于初学者来说,问题就大了,因为完全不明白这其中的道理。
之后便不断的自己尝试和查找资料,虽然脑拙,到现在总算是明显了十之六七。
首先,先要理解一下Android自己原本的布局。
下面这一段是最原始的Android布局的XML代码
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点我" android:id="@+id/button" /> </LinearLayout>
这没什么可以多说的,无非就是一个<LinearLayout>的布局,里面再配了一个Button的按钮。这些都是系统自己定好的,我们直接用就可以了。
还有一种就是我们把LinearLayout这套布局全部改掉。
再看一段代码
<com.tantanwen.dantest_01.views.SliderLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical" android:id="@+id/root_layout"> <Button android:text="@string/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#aaabbb" android:id="@+id/textView1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/page2"> </LinearLayout></com.tantanwen.dantest_01.views.SliderLayout>
看出有什么区别吗,就是<LinearLayout >这个东西变成了<com.tantanwen.dantest_01.views.SliderLayout>
LinearLayout是系统定的,而com.tantanwen.dantest_01.views.SliderLayout是我自己定的,为什么是这以长这么古怪的名字呢?
因为它要和我们的JAVA类对应起来。也就是说,我起了这个名字,同样的,我必须在包com.tantanwen.dantest_01.views下面新建一个叫SliderLayout的类的方法。
而且这个类方法必须继承一个叫ViewGroup的UI界面类,这是Android中的父类,也就是如果涉及到界面上所有的控件的,都是从这个类继承下来的。(还有一个叫View的父类,不过我还没研究过,现在统一从ViewGroup继承)
继承以后,还必需创建对应的构造方法,以及两个需要重写的指定方法,这是系统规定的,如果不这么做,程序就会出错,无法正常编译或是编译了你看不到界面上有任何东西。
为什么呢?因为有些东西你重定义了,所以就必须全部自己指定。
package com.tantanwen.dantest_01.views;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.Button;/** * Created by dan on 2015/6/25. */public class SliderLayout extends ViewGroup { public SliderLayout(Context context) { super(context); } public SliderLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // 这里是指所有布局下面的所有控件,如button,textView什么的,我现在遍历它们 //为什么要遍历?因为我要给他们重定义坐标 for (int i = 0; i < getChildCount(); i++) { //得到这个控件的对象 View child = getChildAt(i); // 取出当前子View长宽 int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); //上面两个对象我没用,有兴趣可以自己研究一下,我现在主要测试显示。 int mLeft; int mTop; if(child instanceof Button) { mLeft = 20; mTop = 80; width = 160; }else{ mLeft = 600; mTop = 0; } /* 调用layout并传递计算过的参数为子view布局 这里有四个值,分别对应什么呢? 从左到右依次:距离控件(你就理解成手机屏幕好了)右边多少距离,距离控件上面多少距离,右边多少距离,下面多少距离。 完成这一步之后,屏幕上才会显示你要的子控件 */ child.layout(mLeft, mTop, mLeft + width, mTop + height); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec,heightMeasureSpec); }}
SliderLayout两个同名的,就是构造方法,不用管,定好的。
onMeasure方法,好吧……查了下资源,说这个方法主要的作用就是测量布局的高度和宽度,再调用父类方法把数值传过吧。
嗯,其实这段目前也是定死的,直接复制着用就行了,必竟还是初学者,没研究到这么深,而且目前也没有特别要用到的这块的地方,照抄就行了。
最后是layout方法,这个方法是用来重新布局我自定义的界面中所有的控件的。
就如同我在函数中写的那样,
getChildCount这个函数是得到所有的控件的数量
比如我前面定义的XML
<Button android:text="@string/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#aaabbb" android:id="@+id/textView1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/page2">
有两个控件,一个按钮Button,一个叫LinearLayout的层
所以getChildCount就是2,做两次循环,然后定义上下左右的方向,重新画到手机屏幕上面。
这里用了一段
if(child instanceof Button) {
我主要是判断一下是否是按钮还是层,把两个控件的坐标拉到不同的地方,以免重合在一起。
最后,我现在代码全写完了,可以编译,实际看一下效果了。
嗯?这样就行了?是的,SliderLayout类里的方法你定义好就行了,系统会自己搞定的。
我试着编译了一下。
已经出现了我想要的效果了,这就是我自己定义的布局,按钮在左边靠上,层在右边,层本身是不可见的,不过我给他加了一段背景图,就变成一个导航条的样子了。
不过……感觉还是怪怪的啊,为什么有种没有撑满整个屏幕的感觉?
其实是因为系统默认的我自定义的层与屏幕两边有边距造成的。我再改一下。
到MainActivity的类中加一段代码:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到我自己定义的层,根据ID,这个ID是我赋给自己定义的层的 mSliderLayers = (SliderLayout)findViewById(R.id.root_layout); //把边距全部调成没有,即0,这也是上下左右四个。 mSliderLayers.setPadding(0,0,0,0); }
好了,我再运行一下
这次总算是正常了。
总算是满足我现在的要求了,第一阶段结束。
- 关于如果自己定义安卓的布局界面的初学研究
- 献给初学安卓的自己。。Android
- 安卓界面布局的一些基本知识
- 打造自己的安卓Metro界面
- 自己关于java界面布局的一点心得
- 关于安卓蓝牙的一些研究
- 关于研究的一个定义
- 黑马程序员-安卓界面布局的基本属性
- 安卓学习笔记----界面的五大布局
- 安卓开发界面的布局显示及其属性
- 安卓:回退栈,类似新闻的布局界面
- 安卓布局——简单的注册界面
- 安卓小学科学实验里的控件布局定义
- 安卓界面布局
- 初学安卓,关于Fragment添加返回栈的笔记
- 打造属于自己的安卓Metro界面
- 安卓应用开发之定义自己的权限
- 关于动态加载布局的想法(初学)
- Myeclipse破解以及注册码
- 手斧Linux – 从LFS到Funtoo (60)
- 手斧Linux – 从LFS到Funtoo (61)
- wordpress支持markdown
- 避免Java应用中NullPointerException的技巧和最佳实践
- 关于如果自己定义安卓的布局界面的初学研究
- 手斧Linux – 从LFS到Funtoo (62)
- 互联网思维
- 手斧Linux – 从LFS到Funtoo (63)
- java读写Mysql数据库乱码
- 结构体数组
- 手斧Linux – 从LFS到Funtoo (64)
- swift中单例实现
- Python和tornado的下载、安装及配置