1.imageviewԴ??
2.ImageView设置backgroundåsrcçåºå«
3.èªå®ä¹View(1)
imageviewԴ??
在探讨之前,让我们明确一点:Android的ImageView实际上并不支持直接加载GIF动图,因为ImageView基于Canvas绘制,而Canvas仅支持drawBitmap一次绘制一张。那么,树里云代理源码Glide是微引擎源码如何巧妙地让ImageView展现出GIF动画的呢?
让我们从Glide的源码入手,今天的主角是GifDrawable。这个类虽然有大约行代码,但理解其工作原理并非无迹可寻。首先,我们注意到一个开始播放第一帧的方法,这可能是入口点。
代码结构中,域名转向源码当GIF有多帧时,会订阅特定事件。关键在于观察三句代码:一是递增帧位置,表明采用无限轮播算法;二是倒数线源码加载资源回调,通过Target接口来触发;三是消息传递,用Handler进行控制。
在加载资源的回调中,我们看到消息机制在发挥作用。店铺招牌源码当接收到消息,会根据what参数进行处理。在handleMessage中,处理了延迟消息和清理消息。延迟消息会获取新帧数据并绘制到ImageView,同时清除旧帧,接着进入下一个帧的加载和清除过程。
总结来说,Glide加载GIF的原理相当直观:GIF被解析为一系列,通过无限轮播,每次新帧的加载都触发一次请求。在完成绘制后,旧帧会被清除,然后继续下一轮的加载。整个过程通过Handler的消息传递机制驱动循环播放。以上内容摘自Android轮子哥的分享。
ImageView设置backgroundåsrcçåºå«
ä»å¤©å¼åçæ¶åéå°ä¸ä¸ªå°é®é¢ï¼å¨ç»ä¸ä¸ªImageViewæ´æ¢å¾ççæ¶åï¼æ使ç¨çæ¯javaçæ¹å¼æ´æ¢ï¼ä½¿ç¨çæ¹æ³æ¯setBackgroundResourceï¼ï¼,ä½å¥æªçæ¯æ»æ¯æ²¡æææã
æåæ¥æåå æ¯ï¼æå¨ç¼åxmlæ件çæ¶åï¼ä¸ºäºæ¥çææï¼ç»è¿ä¸ªImageView设置äºsrcï¼è¿æ¶åå设置backgroundçæ¶åååçéå ã
解å³æ¹æ³ï¼å°xmlä¸çsrcå é¤å³å¯ã
é®é¢å»¶ä¼¸ï¼
ä¸ãImageView设置backgroundåsrcçåºå«ã
1.srcæ¯å¾çå 容ï¼åæ¯ï¼ï¼bgæ¯èæ¯ï¼å¯ä»¥åæ¶ä½¿ç¨ã
2.backgroundä¼æ ¹æ®ImageViewç»ä»¶ç»å®çé¿å®½è¿è¡æ伸ï¼èsrcå°±åæ¾çæ¯åå¾ç大å°ï¼ä¸ä¼è¿è¡æ伸 ã
3.scaleTypeåªå¯¹srcèµ·ä½ç¨ï¼bgå¯è®¾ç½®éæ度ã
äºãImageViewå ç§ä¸åç设置å¾ççæ¹å¼ã
设置backgroundï¼
1.image.setBackground(getResources().getDrawable(R.drawable.blackk));//åå½¢
2.image.setBackgroundResource(R.drawable.blackk);//åå½¢ 3.image.setBackgroundDrawable(getResources().getDrawable(R.drawable.blackk));////åå½¢
æºç ï¼è¿ä¸ç§æ¹æ³çå®è´¨é½æ¯è°ç¨æ¹æ³3setBackgroundDrawable()ã
设置src:
1.image.setImageDrawable(getResources().getDrawable(R.drawable.blackk)); //ä¸ä¼åå½¢
2.Stringpath=Environment.getExternalStorageDirectory()+File.separator+âtest1.jpgâ;
Bitmap bm = BitmapFactory.decodeFile(path);
image.setImageBitmap(bm);//ä¸ä¼åå½¢
3.image.setImageResource(R.drawable.blackk);//ä¸ä¼åå½¢
æºç ï¼ å ¶ä¸æ¹æ³2å°±æ¯å°bitmap转æ¢ä¸ºdrawableç¶åè°ç¨æ¹æ³1ï¼æ¹æ³1åæ¹æ³3é½æ¯è°ç¨updateDrawableï¼ï¼æ¹æ³ã
èªå®ä¹View(1)
ç»åè¿åé¢ä¸ç¯å°å°å¦å¦çåºç¡ç¯ä¹åï¼ç»äºå°äºè¿é¶ç¯ï¼æ£å¼è¿å ¥è§£æèªå®ä¹Viewçé¶æ®µãè³äºæ¬ç« è为ä»ä¹è¦å«è¿é¶ç¯(è½ç¶è®²çæ¯åºç¡çå 容)ï¼å 为ä»æ¬ç¯å¼å§ï¼å°ä¼éæ¸æå¼èªå®ä¹Viewçç¥ç§é¢çº±ï¼æ¯ä¸ç¯é½å°æ¯ä¸ä¸ç¯å 容æ´å æ·±å ¥ï¼å©ç¨æå¦çç¥è¯è½å¤å¶ä½æ´å ç«é ·èªå®ä¹Viewï¼å°±åå¨å°é¶ä¸ä¸æ ·ï¼æ¯ä¸ç¯é½æ´ä¸ä¸å±ï¼ 帮å©å¤§å®¶ä¸æ¥æ¥èµ°å人çå· å³°ï¼åºä»»CEOï¼èµ¢åç½å¯ç¾ã 误ï¼æ¯å¸®å©å¤§å®¶æ´å äºè§£é£äºç«é ·çèªå®ä¹Viewæ¯å¦ä½å¶ä½çï¼è¾¾å°ä¸¾ä¸åä¸çææã
ä½ä¸ºä¸ä¸ª<b>æ(hui)追(zhuang)æ±(B)</b>çç¨åºåï¼è¯å®æ³åä¸äºè®©äººç¼åä¸äº®çç¨åºææï¼ä½æ¯ç³»ç»æä¾çé£äºä¸è¬å¾é¾æ»¡è¶³ï¼ä¸ºäº<b>梦(zhuang)æ³(B)</b>å°±å¿ é¡»è¦å¦ä¹ ä¸äºèªå®ä¹Viewãä¸é¢æ们就äºè§£ä¸äºèªå®ä¹Viewç¸å ³çä¸è¥¿ã
èªå®ä¹ViewGroupä¸è¬æ¯å©ç¨ç°æçç»ä»¶æ ¹æ®ç¹å®çå¸å±æ¹å¼æ¥ç»ææ°çç»ä»¶ï¼å¤§å¤ç»§æ¿èªViewGroupæåç§Layoutï¼å å«æåViewã
ä¾å¦ï¼ä¸ä¸ªåºç¨å çåºé¨å¯¼èªæ¡ä¸çæ¡ç®ï¼ä¸è¬é½æ¯ä¸é¢ä¸ºå¾æ ï¼ä¸é¢æ¯æåï¼é£ä¹è¿ä¸¤ä¸ªå°±å¯ä»¥ç¨èªå®ä¹ViewGroupç»åæ为ä¸ä¸ªVeiwï¼æä¾ä¸¤ä¸ªå±æ§åå«ç¨æ¥è®¾ç½®æååå¾çå³å¯ï¼è¿æ ·ä½¿ç¨èµ·æ¥ä¼æ¹ä¾¿å¾å¤ã
å¨æ²¡æç°æçViewï¼éè¦èªå·±å®ç°çæ¶åï¼å°±ä½¿ç¨èªå®ä¹Viewï¼ä¸è¬ç»§æ¿èªViewï¼SurfaceViewæå ¶ä»çViewï¼ä¸å å«åViewã
ä¾å¦ï¼å®ä¹ä¸ä¸ªæ¯æèªå¨å è½½ç½ç»å¾ççImageViewï¼æå¶ä½ä¸ç§ç¹æ®çå¨ç»ææã
<b>ä¸è¬æ¥è¯´ï¼èªå®ä¹Viewå¨å¤§å¤æ°æ åµä¸é½ææ¿ä»£æ¹æ¡ï¼å©ç¨å¾çæè ç»åå¨ç»æ¥å®ç°ï¼ä½æ¯ä½¿ç¨åè å¯è½ä¼é¢ä¸´å åèè´¹è¿å¤§ï¼å¶ä½éº»ç¦æ´è¯¸å¤é®é¢ã</b>
Viewçæé å½æ°æåç§éè½½åå«å¦ä¸
å¯ä»¥çåºï¼å ³äºViewæé å½æ°çåæ°æå¤æå°ï¼å æé¤å 个ä¸å¸¸ç¨çï¼çä¸å¸¸ç¨çåç 究ã
<b>æå个åæ°çæé å½æ°å¨APIçæ¶åææ·»å ä¸ï¼æä¸è¬ä¸ä½¿ç¨ï¼æä¸èèã</b>
æä¸ä¸ªåæ°çæé å½æ°ä¸ç¬¬ä¸ä¸ªåæ°æ¯é»è®¤çStyleï¼è¿éçé»è®¤çStyleæ¯æå®å¨å½åApplicationæActivityæç¨çThemeä¸çé»è®¤Styleï¼ä¸åªæå¨æç¡®è°ç¨çæ¶åæä¼çæï¼ä»¥ç³»ç»ä¸çImageButton为ä¾è¯´æï¼
<b>注æï¼å³ä½¿ä½ å¨Viewä¸ä½¿ç¨äºStyleè¿ä¸ªå±æ§ä¹ä¸ä¼è°ç¨ä¸ä¸ªåæ°çæé å½æ°ï¼æè°ç¨çä¾æ§æ¯ä¸¤ä¸ªåæ°çæé å½æ°ã</b>
<b>ç±äºä¸ä¸ªåæ°çæé å½æ°ç¬¬ä¸ä¸ªåæ°ä¸è¬ä¸ç¨ï¼æä¸èèï¼ç¬¬ä¸ä¸ªåæ°çå ·ä½ç¨æ³ä¼å¨ä»¥åç¨å°çæ¶å详ç»ä»ç»ã</b>
æé¤äºä¸¤ä¸ªä¹åï¼åªå©ä¸ä¸ä¸ªåæ°å两个åæ°çæé å½æ°ï¼ä»ä»¬ç详æ å¦ä¸ï¼
以ä¸æ¹æ³è°ç¨çæ¯<b>ä¸ä¸ªåæ°</b>çæé å½æ°ï¼
以ä¸æ¹æ³è°ç¨çæ¯<b>两个åæ°</b>çæé å½æ°ï¼
å ³äºæé å½æ°å 讲è¿ä¹å¤ï¼å ³äºå¦ä½èªå®ä¹å±æ§å使ç¨attrsä¸çå 容ï¼å¨åé¢ä¼è¯¦ç»è®²è§£ï¼ç®ååªéè¦ç¥éè¿ä¸¤ä¸ªæé å½æ°å¨ä½æ¶è°ç¨å³å¯ã
========
æµéView大å°ä½¿ç¨çæ¯onMeasureå½æ°ï¼æ们å¯ä»¥ä»è¿ä¸¤ä¸ªåæ°ååºå®½é«çç¸å ³æ°æ®ï¼
ä»ä¸é¢å¯ä»¥çåº onMeasure å½æ°ä¸æ widthMeasureSpec å heightMeasureSpec è¿ä¸¤ä¸ª int ç±»åçåæ°ï¼ 毫æ çé®ä»ä»¬æ¯å宽é«ç¸å ³çï¼ <b>ä½å®ä»¬å ¶å®ä¸æ¯å®½åé«ï¼ èæ¯ç±å®½ãé«ååèªæ¹åä¸å¯¹åºç模å¼æ¥åæçä¸ä¸ªå¼ï¼</b>
å¨intç±»åçä½äºè¿å¶ä½ä¸ï¼-è¿ä¸¤ä½è¡¨ç¤ºæ¨¡å¼,~0è¿ä¸åä½è¡¨ç¤ºå®½åé«çå®é å¼ã
以æ°å¼(äºè¿å¶ä¸º: )为ä¾(å ¶ä¸æ¨¡å¼åå®é æ°å¼æ¯è¿å¨ä¸èµ·çï¼ä¸ºäºå±ç¤ºæå°ä»ä»¬åå¼äº)ï¼
å®é ä¸å ³äºä¸é¢çä¸è¥¿äºè§£å³å¯ï¼å¨å®é è¿ç¨ä¹ä¸åªéè¦è®°ä½æä¸ç§æ¨¡å¼ï¼ç¨ MeasureSpec ç getSizeæ¯è·åæ°å¼ï¼ getModeæ¯è·å模å¼å³å¯ã
å¦æ对Viewç宽é«è¿è¡ä¿®æ¹äºï¼<b>ä¸è¦è°ç¨super.onMeasure(widthMeasureSpec,heightMeasureSpec);</b>
è¦è°ç¨<b>setMeasuredDimension(widthsize,heightsize);</b> è¿ä¸ªå½æ°ã
======
è¿ä¸ªå½æ°å¨è§å¾å¤§å°åçæ¹åæ¶è°ç¨ï¼
onSizeChangedå¦ä¸ï¼
å¯ä»¥çåºï¼å®åå个åæ°ï¼åå«ä¸º 宽度ï¼é«åº¦ï¼ä¸ä¸æ¬¡å®½åº¦ï¼ä¸ä¸æ¬¡é«åº¦ã
è¿ä¸ªå½æ°æ¯è¾ç®åï¼æ们åªéå ³æ³¨ 宽度(w), é«åº¦(h) å³å¯ï¼è¿ä¸¤ä¸ªåæ°å°±æ¯Viewæç»ç大å°ã
=========
<b>ç¡®å®å¸å±çå½æ°æ¯onLayoutï¼å®ç¨äºç¡®å®åViewçä½ç½®ï¼å¨èªå®ä¹ViewGroupä¸ä¼ç¨å°ï¼ä»è°ç¨çæ¯åViewçlayoutå½æ°ã</b>
ä¸è¿å ³äºViewçlayoutå½æ°æ们ä¸è¬æ éå ³æ³¨ï¼å 为å¨ä¸è¬æ åµä¸æ们åªéå ³æ³¨Viewèªèº«çåæ ç³»å³å¯ï¼é¤éViewç¶æä¸å¨ç¶VIewæå¤ä½ç½®ç¸å ³ã
å¨èªå®ä¹ViewGroupä¸ï¼onLayoutä¸è¬æ¯å¾ªç¯ååºåViewï¼ç¶åç»è¿è®¡ç®å¾åºå个åViewä½ç½®çåæ å¼ï¼ç¶åç¨ä»¥ä¸å½æ°è®¾ç½®åViewä½ç½®ã
å个åæ°åå«ä¸ºï¼
å ·ä½å¯ä»¥åè åæ ç³» è¿ç¯æç« :
PSï¼å ³äºonLayoutè¿ä¸ªå½æ°å¨è®²è§£èªå®ä¹ViewGroupçæ¶åä¼è¯¦ç»è®²è§£ã
========
onDrawæ¯å®é ç»å¶çé¨åï¼ä¹å°±æ¯æ们çæ£å ³å¿çé¨åï¼ä½¿ç¨çæ¯Canvasç»å¾ã
å ³äºCanvasç»å¾å¦åä¸ç« å§ï¼æ¬æ¥æ³åä¸äºå ³äºCanvasåºæ¬æä½ççï¼å¯æ¯ç¯å¹ 太é¿äºQAQï¼ ç个尾巴ä¸ä¸ç¯ååå§ï¼æ¯ç«Canvasç»å¾ä¹æ¯ä¸ä¸ªæ¯è¾åºå¤§çä¸è¥¿ï¼ä¹ä¸æ¯ä¸è¨ä¸¤è¯å°±è½è®²æç½çï¼å°±å°è¿éå§ã
======
èªå®ä¹å®Viewä¹åï¼ä¸è¬ä¼å¯¹å¤æ´é²ä¸äºæ¥å£ï¼ç¨äºæä½Viewçç¸å ³å±æ§ï¼æ§å¶Viewçç¶æçï¼æè éè¦çå¬Viewçååï¼å ·ä½è¿æ¯ç¨åå讲å§(继ç»æå)ã
PS ï¼å®é ä¸ViewGroupæ¯Viewçä¸ä¸ªåç±»ã
View
ViewGroup
View.MeasureSpec
onMeasureï¼MeasureSpecæºç æµç¨ æ路详解
Androidä¸èªå®ä¹æ ·å¼ä¸Viewçæé å½æ°ä¸ç第ä¸ä¸ªåæ°defStyleçæä¹
android viewæé å½æ°ç 究
Android Viewæé æ¹æ³ç¬¬ä¸åæ°ä½¿ç¨æ¹æ³è¯¦è§£
Android èªå®ä¹View onMeasureæ¹æ³çå®ç°
Android APIæå(äº)èªå®ä¹æ§ä»¶ä¹ onMeasure
Androidä¸Viewçç»å¶è¿ç¨ onMeasureæ¹æ³ç®è¿°