面试总结(4):top、left、right、bottom 和

作者: 珠穆朗玛小王子 | 来源:发表于2017-09-12 17:00 被阅读0次

    前言#

    这是前几天面试的时候遇到的一个问题,之前没有专门去研究这三个概念的区别,所以就凭印象回答了这道题,回来就实际研究一下,发现自己回答还算可以吧。

    正文#

    <h2>top、left、right、bottom</h2>

    经过我的亲身测试,总结如下:

    top、left、right、bottom 都是以父View作为参考物的返回的坐标值。
    top:距离父容器的y距离。
    left:距离父容器的x距离。
    right:left + view本身的宽度。
    bottom:top + view本身的高度。

    padding值对于 top、left、right、bottom 无影响(因为宽度没有发生改变)
    margin值对于top、left、right、bottom 有影响(不影响宽高,但是margin会改变left和top,所以就直接影响了right和bottom)

    top的最小值是 -viewHeight
    left的最小是-viewWidth

    <h2>translationX、translationY</h2>

    这个其实就非常好理解了,这两个方法使用的也是比较多,就是相对于自身的位置进行偏移的值。

    translationX:相对于最初位置的x方向的偏移值
    translationY:相对于最初位置的y方向的偏移值。

    仅仅是显示的位置出现了偏移,但是view的实际位置并没有发生改变,所以这两个值对于top、left、right、bottom是没有影响的。

    <h2>scrollX,scrollY</h2>

    scrollX:表示view在x方向的滚动的距离。
    scrollY:表示view在y方向的滚动的距离。

    这个理解起来也非常简单,我们也经常用来检查是否滚动到顶部、底部或者其他的操作,但是他俩对于top、left、right、bottom是否有影响呢?

    以android本身自带的具有滚动特性的View来做个试验:

    1、scrollView

    MyScrollView scrollView = (MyScrollView) findViewById(R.id.scrollView);
    linearLayout = findViewById(R.id.linearLayout);
    
    scrollView.setListener(new MyScrollView.OnScrollListener() {
        @Override
        public void onScroll(int l, int t, int oldl, int oldt) {
                    Log.e("lzp", "top:" + linearLayout.getTop()
                            + " left:" + linearLayout.getLeft()
                            + " right:" + linearLayout.getRight()
                            + " bottom:" + linearLayout.getBottom());
                }
            });
    

    直接打印scrollView中的第一个子控件Linearlayout的四个值:

    这里写图片描述

    从log上看,scrollView对于linearlayout是没有影响的。

    2、ListView

    listView  = (ListView) findViewById(R.id.listView);
            listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                    new String[]{"111","111","111","111","111","111","111","111",
                            "111","111","111","111","111","111","111","111",
                            "111","111","111","111","111","111","111","111","111"}));
            final View header = getLayoutInflater().inflate(R.layout.header, listView, false);
            listView.addHeaderView(header);
            listView.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
    
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    Log.e("lzp", "top:" + header.getTop()
                            + " left:" + header.getLeft()
                            + " right:" + header.getRight()
                            + " bottom:" + header.getBottom());
                }
            });
    

    代码里,我们在listView滚动的时候打印header的四个值:

    这里写图片描述

    从结果上看,listview对于子View的top、left、right、bottom是有影响。

    那为什么同样是滚动,却得到了两个完全不一样的结果呢?

    其实这个问题并不难解释,这和两个控件的内部特性有关系:

    1、top、left、right、bottom的值,是在view的onLayout的时候确定。

    2、scrollView只在绘制的时候onLayout,在滚动的时候不会再次出发onLayout,所以对于子View的top、left、right、bottom是没有影响的、

    3、listView自身有回收机制,所以在滚动的时候需要时刻去检测item是否已经滚动出了屏幕,这样就需要重新测量子view的位置,所以就直接影响了item的top、left、right、bottom。

    总结#

    这几个概念的解释和相互之间的关系我们都已经弄清楚了,top、left、right、bottom依赖于界面的onLayout,只要会触发onLayout就可能会影响到他们的值。

    translationX、translationY、scrollX、scrollY都是比较独立的概念,理解起来就简单一点。

    下一篇接着写面试总结:Fragment的懒加载。

    相关文章

      网友评论

        本文标题:面试总结(4):top、left、right、bottom 和

        本文链接:https://www.haomeiwen.com/subject/eyocsxtx.html