ViewGroup的onLayout、layout方法

来源:互联网 发布:编程培训班多少钱 编辑:程序博客网 时间:2024/05/17 13:39

onLayout、layout方法简介

onLayout方法是ViewGroup中子View的布局方法,用于放置子View的位置。放置子View很简单,只需在重写onLayout方法,然后获取子View的实例,调用子View的layout方法实现布局。在实际开发中,一般要配合onMeasure测量方法一起使用。

onLayout方法:

@Overrideprotected abstract void onLayout(boolean changed,            int l, int t, int r, int b);

该方法在ViewGroup中定义是抽象函数,继承该类必须实现onLayout方法,而ViewGroup的onMeasure并非必须重写的。View的放置都是根据一个矩形空间放置的,onLayout传下来的l,t,r,b分别是放置父控件的矩形可用空间(除去margin和padding的空间)的左上角的left、top以及右下角right、bottom值。


layout方法:

public void layout(int l, int t, int r, int b);

该方法是View的放置方法,在View类实现。调用该方法需要传入放置View的矩形空间左上角left、top值和右下角right、bottom值。这四个值是相对于父控件而言的。例如传入的是(10, 10, 100, 100),则该View在距离父控件的左上角位置(10, 10)处显示,显示的大小是宽高是90(参数r,b是相对左上角的),这有点像绝对布局。


平常开发所用到RelativeLayout、LinearLayout、FrameLayout...这些都是继承ViewGroup的布局。这些布局的实现都是通过都实现ViewGroup的onLayout方法,只是实现方法不一样而已。


下面是一个自定义ViewGroup的Demo,用onLayout和layout实现子View的水平放置,间隔是20px

public class MyViewGroup extends ViewGroup {     // 子View的水平间隔    private final static int padding = 20;         public MyViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }     @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // TODO Auto-generated method stub                 // 动态获取子View实例        for (int i = 0, size = getChildCount(); i < size; i++) {            View view = getChildAt(i);            // 放置子View,宽高都是100            view.layout(l, t, l + 100, t + 100);            l += 100 + padding;        }             }     }

Activity的XML布局:

<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:padding="10dp">     <com.example.layout.myviewgroup android:layout_width="match_parent" android:layout_height="100dp" android:background="#0000ff">                 <view android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff0000">        <view android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ff00">             </view></view></com.example.layout.myviewgroup> </relativelayout>



效果如图所示:


上图MyViewGroup是蓝色,两个子View分别为红色和绿色。


在自定义View中,onLayout配合onMeasure方法一起使用,可以实现自定义View的复杂布局。自定义View首先调用onMeasure进行测量,然后调用onLayout方法,动态获取子View和子View的测量大小,然后进行layout布局。


Android 三种布局实现上下回弹效果(普通布局,ListView,ScrollView)

三种布局实现上下回弹效果(普通布局,ListView,ScrollView),有需要的朋友可以参考下。


本文主要介绍不超出屏幕边界的普通布局,ListView,ScrollView三种布局上下回弹效果的实现。
实现流程:
1.新建一个类继承LinearLayout
2.覆写方法三个方法onLayout(boolean changed, int l, int t, int r, int b),computeScroll(),onTouchEvent(MotionEvent event)
3.在构造方法中实例化Scroller;
4.在OnLayout里面实例化子布局
5.在OnonTouchEvent里面进行手势判断,
6.在computeScroll()里面完成实际的滚动
由于本人深恶痛绝下载源码需要财富的现象,现把源码放在这里与大家分享,代码稍微改一下就可以实现一切布局的回弹效果
这里只实现ScrollView回弹效果,其他一切布局的回弹效果的实现均雷同于此


package com.example.scrollview.springback;import android.annotation.SuppressLint;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.LinearLayout;import android.widget.ScrollView;import android.widget.Scroller;public class ScrollViewLinearLayout extends LinearLayout implements OnTouchListener{private LinearLayout top;//private LinearLayout.LayoutParams top_lp ;private ScrollView sv;private boolean isfrist =true;private float y1,y2;private int hight=60;private Scroller mScroller;public ScrollViewLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);setClickable(true); setLongClickable(true);mScroller = new Scroller(context);}protected void smoothScrollBy(int dx, int dy) { //设置mScroller的滚动偏移量 mScroller.startScroll(0, mScroller.getFinalY(), 0, dy); invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果 } protected void smoothScrollTo(int fx, int fy) { int dx = fx - mScroller.getFinalX(); int dy = fy - mScroller.getFinalY(); smoothScrollBy(0, dy); } @SuppressLint("NewApi")@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if(changed&&isfrist){//只需实例化一次sv= (ScrollView) getChildAt(0);//该自定义布局写入xml文件时,其子布局的第一个必须是ScrollView时,这里才能getChildAt(0),实例化ScrollViewsv.setOverScrollMode(View.OVER_SCROLL_NEVER);//去掉ScrollView 滑动到底部或顶部 继续滑动时会出现渐变的蓝色颜色快sv.setOnTouchListener(this);isfrist=false;}}@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { //判断mScroller滚动是否完成scrollTo(mScroller.getCurrX(), mScroller.getCurrY());//这里调用View的scrollTo()完成实际的滚动postInvalidate(); } super.computeScroll(); }@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN: y1= event.getY();break; case MotionEvent.ACTION_MOVE:y2= event.getY();int scrollY=v.getScrollY(); int height=v.getHeight(); int scrollViewMeasuredHeight=sv.getChildAt(0).getMeasuredHeight();if(y2-y1>0&&v.getScrollY()<=0){//头部回弹效果smoothScrollTo(0,-(int) ((y2-y1)/2));System.out.println("topMargin="+((int) ((y2-y1)/2)));return false;}if(y2-y1<0&&(scrollY+height)==scrollViewMeasuredHeight){//底部回弹效果smoothScrollTo(0,-(int) ((y2-y1)/2));return false;}break;case MotionEvent.ACTION_UP:smoothScrollTo(0, 0);//松开手指,自动回滚break;default: break;}return false;}}



需要注意的有以下几点:
1.mScroller.startScroll(0, mScroller.getFinalY(), 0, dy); 后必须invalidate();才能调用computeScroll()看到滚动效果
2.Scroller 的滚动坐标是屏幕左上角为坐标原点,往右是+x,往下是-y.(这一点在计算坐标时一定要明白,否则很难理解坐标的计算)
3.该自定义布局写入xml文件时,其子布局的第一个必须是ScrollView时,在OnLayout()方法才能getChildAt(0)实例化ScrollView
4.上下回弹效果的关键方法是判断ScrollView何时到头部和底部,这样才能触发拉伸,回弹效果


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 期望薪资说低了怎么办 期望薪资说高了怎么办 面试工资说低了怎么办 期望薪资谈低了怎么办 请年假公司不批怎么办 期望工资填低了怎么办 面试工资要高了怎么办 找工作期望薪资写低了怎么办 期望工资写少了怎么办 不给工人发工资怎么办 天亮了怎么办我好想你 亲爱的我想你我怎么办 人在澳大利亚悉尼找不到了怎么办 红米手机忘记手势密码怎么办 捡到苹果手机怎么办才能自己用 日语会读不会写怎么办 手术后nbp过低怎么办 我的手破了怎么办英文 平板手机屏坏了怎么办 他很优秀我该怎么办 洗澡的花洒漏水怎么办 高三了文科成绩很差怎么办 骑缝章最后一页没盖全怎么办 机票取早了没有登机口怎么办 机票早订比晚订贵怎么办? 孩子考差了父母怎么办 保险公司不给业务员办退司怎么办 我不习惯没有你我怎么办 锁坏了打不开了怎么办 要上班老人生病无人照顾怎么办 苹果手机一直说英文怎么办 公司很抠门怎么办英文怎么说 过了截港时间怎么办 截关日期是假日怎么办 恒温阀冷水进水堵塞怎么办 缺氧液泵管道堵塞怎么办 货物包装大集装箱装不下怎么办 微信收藏的视频格式错误怎么办 乙方被刑拘房租未付清怎么办 房贷银行卡号弄错怎么办 社保卡号弄错了怎么办