Android面试-View相关


    view绘制、事件分发、listview缓存

>>> View绘制机制:{
    view树的绘制流程、measure、layout、draw

===view树的绘制流程:[
    measure<是否重新计算视图大小> --->layout<是否重新安置视图位置>----->draw<是否需要重绘>   是一个递归过程

---measure测量:树的递归过程,自上而下有序进行遍历
--->参数
1、ViewGroup.LayoutParams:设置宽高
2、MeasureSpec:测量规格,包含两种,一种是测量它的模式;第二种是在这种模式下测量的大小。
--->重要方法
1、measure:最终还是调用了onMeasure方法
2、onMeasure:测量逻辑的方法,两个参数,宽高的测量规格。抽象方法,需要自定义。
3、setMeasuredDimension():将测量好的规格,完成整个测量过程

---layout:树的递归过程,自上而下有序进行遍历。根据测量的尺寸来摆放子视图的位置。
1、layout:最终调用onLayout方法
2、onLayout:抽象方法,需要自定义。分垂直方向和水平方向的布局。

---onDraw:

---两个容易混淆的方法<回调>:
1、invalidate():请求系统,如果视图没有发生变化就不会绘制。
2、requestLayout():当布局发生变化的时候<方向、尺寸>会调用,它就会去出发measure和layout方法,但是它不会调用draw方法。

]

}

>>> 事件分发:{  事件传递、事件分发:
    为什么会有事件分发、三个重要的事件分发方法、事件分发流程

===为什么会有事件分发:[
    Android中的view是以树型结构摆放的,可能有多个view重叠在一起,点击重叠的view会同时响应。
    安卓上面的view是树型结构的,View可能会重叠在一起,当我们点击的地方有多个View都可以响应的时候,这个点击事件应该给谁呢?为了解决这一个问题,就有了事件分发机制。
    PhoneWindow---DecorView----RootView-----ViewGroupA----View1
    没有View遮挡的部分会显示主题的颜色,主题的颜色和标题栏是在DecorView中的。
---Window:抽象类,它是所有视图最顶层的容器,包括了背景的显示、标题栏和事件的处理。
---PhoneWindow:是Window的唯一实现类,是View的事件管理容器。
---DecorView:是PhoneWindow的内部类,来进行消息的传递。
]

===三个重要的事件分发方法:[
    Activity和View是没有第二个拦截的,Activity作为整个事件的原始分发者,如果Activity拦截了这个事件就会导致整个页面没法相应,View作为整个事件传递的末端,要么消费事件,要么就不处理进行回传。
1、dispatchTouchEvent:分发,决定了它的触摸事件是由自己处理还是分发给子View,让子View递归调用自身dispatchTouchEvent方法来处理。在dispatchTouchEvent源码中会调用onInterceptTouchEvent来判断是否要进行拦截。
2、onInterceptTouchEvent:用来拦截事件,当父控件下发事件给子控件进行处理的时候,如果子控件需要对控件进行处理,就会在此方法中进行拦截,然后在子控件中onTouchEvent处理。
3、onTouchEvent:触摸事件<手势事件>,是View中的一个方法。
]

===事件分发流程:[
    当屏幕被点击的时候:Activity --->PhoneWindow --->DecorView --->ViewGroup ---->....... ----->View。如果分发到最后一个View,也没有处理事件,事件会依次返转,最后回转到最高位的Activity,如果Activity还没处理,事件才会被抛弃。这是责任链设计模式。既保证了事件的有序性,又非常灵活。

]

}

>>> listview缓存:{
    什么是listview、listview适配器模式、listview的recycleBin机制、listview的优化

===什么是listview:[
    ListView就是一个能数据集合以动态滚动的方式展示到用户界面上的View。
]

===listview适配器模式:[
    Adapter是ListView和数据之间的桥梁,为了保证数据和View的分离。
]

===listview的recycleBin机制:[
--- private View[] mActiveViews = new View[0];  用于存储活动的View,代表可见的View,这些View是可以直接被复用。
---  private ArrayList<View>[] mScrapViews;   //所有废弃的View,即划出屏幕的View。
--- private ArrayList<View> mCurrentScrap;   //当前被滑出去的View,被废弃的View集合。

---public void setViewTypeCount(int viewTypeCount) {    //为ListView中的每一个数据项建立一个recycleBin机制
---  void fillActiveViews(int childCount, int firstActivePosition) {  //填充
---View getActiveView(int position) {    //获取相应屏幕上显示的View
--- void addScrapView(View scrap, int position) {   //缓存废弃的View
    ListView中屏幕可见的才会保存在内存中,移除屏幕后加入RecycleBin,再次进入屏幕的从RecycleBin获取。
]

===ListView优化:[
    public View getView( int position,View convertView,ViewGroup parent )   //convertView 缓存
1、contentView重用 / viewHolder:contentView缓存的作用,复用控件;viewHolder避免多次findViewByid,减少查找控件的次数,布局二叉树结构,每次遍历都很耗时。
2、三级缓存 / 监听滑动事件: 图片加载的时候需要用到缓存,尽量在getView中少做耗时操作,保证ListView滑动的流畅性。  如果一定要做耗时操作,可以设置监听滑动事件,等滑动停止过后再去加载整个图片。
3、避免使用半透明元素,半透明绘制比不透明更耗时。
4、开启硬件加速。
       @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item, null);
                holder.img = (ImageView) convertView.findViewById(R.id.img);
                holder.title = (TextView) convertView.findViewById(R.id.title);
                holder.info = (TextView) convertView.findViewById(R.id.info);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.title.setText("Hello");
            holder.info.setText("World");
            return convertView;
        }
]

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值