Android的Gif動畫載入
我們都知道Android是不直接支援Gif檔案的載入的(當然了現在的Glide圖片載入框架是支援GIF格式的檔案的,Picasso暫時是不支援的,但是為了這一個小小的功能卻匯入一個庫豈不是得不償失,另外我們這裡主要是學習),但是有時候美工會直接給我們Gif格式的檔案,這時候如果能夠直接使用的話豈不是比使用逐幀動畫方便一些(先不考慮效能的問題),那麼我們就會想辦法,下面是一個自定義的GifView
<declare-styleable name="GifView"> <attr name="gif" format="reference"/> <attr name="paused" format="boolean"/> </declare-styleable> <declare-styleable name="CustomTheme"> <attr name="gifViewStyle" format="reference"/> </declare-styleable>
使用的時候就像ImageView一樣,這裡的iv就是gif檔案,不過是在raw檔案下public class GifView extends View { /** * 預設為1秒 */ private static final int DEFAULT_MOVIE_DURATION = 1000; private int mMovieResourceId; private Movie mMovie; private long mMovieStart; private int mCurrentAnimationTime = 0; private float mLeft; private float mTop; private float mScale; private int mMeasuredMovieWidth; private int mMeasuredMovieHeight; private boolean mVisible = true; private volatile boolean mPaused = false; public GifView(Context context) { this(context, null); } public GifView(Context context, AttributeSet attrs) { this(context, attrs, R.styleable.CustomTheme_gifViewStyle); } public GifView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setViewAttributes(context, attrs, defStyle); } @SuppressLint("NewApi") private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); } // 從描述檔案中讀出gif的值,創建出Movie例項 final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifView, defStyle, R.style.AppTheme); mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -1); mPaused = array.getBoolean(R.styleable.GifView_paused, false); array.recycle(); if (mMovieResourceId != -1) { mMovie = Movie.decodeStream(getResources().openRawResource( mMovieResourceId)); } } /** * 設定gif圖資源 * * @param movieResId */ public void setMovieResource(int movieResId) { this.mMovieResourceId = movieResId; mMovie = Movie.decodeStream(getResources().openRawResource( mMovieResourceId)); requestLayout(); } public void setMovie(Movie movie) { this.mMovie = movie; requestLayout(); } public Movie getMovie() { return mMovie; } public void setMovieTime(int time) { mCurrentAnimationTime = time; invalidate(); } /** * 設定暫停 * * @param paused */ public void setPaused(boolean paused) { this.mPaused = paused; if (!paused) { mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime; } invalidate(); } /** * 判斷gif圖是否停止了 * * @return */ public boolean isPaused() { return this.mPaused; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMovie != null) { int movieWidth = mMovie.width(); int movieHeight = mMovie.height(); int maximumWidth = MeasureSpec.getSize(widthMeasureSpec); float scaleW = (float) movieWidth / (float) maximumWidth; mScale = 1f / scaleW; mMeasuredMovieWidth = maximumWidth; mMeasuredMovieHeight = (int) (movieHeight * mScale); setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight); } else { setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight()); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mLeft = (getWidth() - mMeasuredMovieWidth) / 2f; mTop = (getHeight() - mMeasuredMovieHeight) / 2f; mVisible = getVisibility() == View.VISIBLE; } @Override protected void onDraw(Canvas canvas) { if (mMovie != null) { if (!mPaused) { updateAnimationTime(); drawMovieFrame(canvas); invalidateView(); } else { drawMovieFrame(canvas); } } } @SuppressLint("NewApi") private void invalidateView() { if (mVisible) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { postInvalidateOnAnimation(); } else { invalidate(); } } } private void updateAnimationTime() { long now = android.os.SystemClock.uptimeMillis(); // 如果第一幀,記錄起始時間 if (mMovieStart == 0) { mMovieStart = now; } // 取出動畫的時長 int dur = mMovie.duration(); if (dur == 0) { dur = DEFAULT_MOVIE_DURATION; } // 算出需要顯示第幾幀 mCurrentAnimationTime = (int) ((now - mMovieStart) % dur); } private void drawMovieFrame(Canvas canvas) { // 設定要顯示的幀,繪製即可 mMovie.setTime(mCurrentAnimationTime); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.scale(mScale, mScale); mMovie.draw(canvas, mLeft / mScale, mTop / mScale); canvas.restore(); } @SuppressLint("NewApi") @Override public void onScreenStateChanged(int screenState) { super.onScreenStateChanged(screenState); mVisible = screenState == SCREEN_STATE_ON; invalidateView(); } @SuppressLint("NewApi") @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); mVisible = visibility == View.VISIBLE; invalidateView(); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); mVisible = visibility == View.VISIBLE; invalidateView(); } }
//設定gif動畫
mGifView = (GifView) findViewById(R.id.mygifview);
mGifView.setMovieResource(R.raw.iv);
相關推薦
做一個可複用的 echarts-vue 元件(延遲動畫載入)
在 vue 專案使用 echarts 的場景中,以下三點不容忽視:1. 視覺化的資料往往是非同步載入的;2. 若一個頁面存在大量的圖表( 尤其當存在關係圖和地圖時 ),往往會導致該頁面的渲染速度很慢並可能在幾秒內卡死,產生極差的使用者體驗。3. 引入 echarts 元件導致編譯後的檔案過大從而使得首次訪
一個很low的 動畫載入效果(keyframes )
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鳥教程(runoob.com)</title> <style> div { max-w
flask加vue 動畫 載入更多
曾經使用flask_paginate(地址:https://blog.csdn.net/qq_42239520/article/details/80378095)進行分頁,現在又想新的想法,怎麼才能和其它大多數主流網站一樣,通過點選載入更多,獲取到更多的頁面呢? 原始碼地址:h
Android DrawableAnimation逐幀動畫載入多圖(OOM的解決)
想做一個逐幀動畫,用了一百來張圖片,結果記憶體溢位了,找了半天最後算是解決了。 本來是在drawable裡面寫一個animation-list,設定ImageView的backgroud, 然後在Activity裡面animationDrawable = (Animatio
幀動畫載入大量圖片OOM的解決辦法
這是在別人程式碼基礎上更改的。 程式碼如下: public class SceneAnimation { /** * target imageView */ private ImageView mImageView;
Android的Gif動畫載入
我們都知道Android是不直接支援Gif檔案的載入的(當然了現在的Glide圖片載入框架是支援GIF格式的檔案的,Picasso暫時是不支援的,但是為了這一個小小的功能卻匯入一個庫豈不是得不償失,另外我們這裡主要是學習),但是有時候美工會直接給我們Gif格式的檔案,這時候
Android逐幀動畫,逐幀動畫載入圖片過多時OOM異常的解決和替代方法
1.首先新增逐幀動畫 播放逐幀動畫,在工程中res目錄下建立一個anim資料夾,新增動畫anim_welcome.xml檔案如下: <?xml version="1.0" encoding="utf-8"?> <animation-li
FBX動畫載入功能 程式實現(一)
FBX 動畫資料結構 解釋 FbxScene 一個場景包含一個或者跟多的動畫棧。如過在場景中沒有動畫,那麼你將不需要用到動畫棧或者其他動畫類成員 FbxAnimStack 動畫棧是用來包含一個或者多個動畫圖層的最高等級的容器 FbxAnimLayer
cocos2d-x 動畫載入 延時執行
void SnatchDeveloper::hechengframeCacheAction() { CCArray * hechengFrames=CCArray::create(); for (int i=0; i<8; i++)
【跟我一起學Unity3D】代碼中分割圖片而且載入幀序列動畫
stream textfield 控制 調整 我們 pos apply fonts 一個 在Cocos2dx中。對大圖的處理已經封裝好了一套自己的API,可是在Unity3D中貌似沒有類似的API(好吧,實際上是有的,並且功能更強大),或
CSharpGL(50)使用Assimp載入骨骼動畫
CSharpGL(50)使用Assimp載入骨骼動畫 在(http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html)介紹了C++用Asismp庫載入骨骼動畫的原理和流程。 在(http://wiki.jikexueyuan.com/project
flutter動畫和進行圖片的載入
1.進行簡單的移動,旋轉等動畫操作,具體的操作可以檢視api transform: new Matrix4.rotationZ(0.1), 沿z軸旋轉 transform: new Matrix4.translationValues(10.0, 30.0, 30.0), 2.對於Contai
網頁頁面預載入動畫的實現,載入後隱藏
我們做web app的時候,可以做一個頁面載入廣告,在你網頁載入的時候,先出現一段gif動圖或者是海報。 下面是實現頁面載入動畫的程式碼 首先js程式碼的實現 (function($){ $(window).load(function(){ $('#b
android 動畫--幀動畫--仿美團載入中小人
1 把資源圖片放到drawable中 2 在drawable中寫動畫的xml檔案animation01 Animation01.xml <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:a
Android正在載入動畫
LoadingImage 正在載入的ImageView 使用方法 maven <dependency> <groupId>com.hlq</groupId> <artifactId>loading
安卓-Loading載入中動畫
前段時間用到了loading載入動畫,這裡記錄兩種方法。一種是多個影象變化組成的動畫,一種圖片本身的動作,以轉圈為例下面是程式碼。 這是效果圖 原始碼下載地址 Loading載入中動畫專案原始碼下載 第一種多個圖片變化 在res的anim資料夾中新建一個loadingf
CSS3載入等待動畫(loading)
效果: CSS樣式表程式碼: #errmsg { color: #ff0000; text-align: center; margin: 0px auto; line-height: 30px; } #colorfulPulse { width
ajax 非同步載入載入動畫
1.當資料恢復後臺程式碼處理量較大時,希望前臺能夠有個提示或者動畫,讓使用者知道後臺在運轉,讓使用者體驗好點 $.ajax({ url: '${ctx}/admin/course/sysAllContainerToCourse.json', data: param, type:
OkHttp網路載入資料+RecyclerView展示+屬性動畫
MainActivity.java public class MainActivity extends AppCompatActivity implements HttpUrls.ff{ private ImageView mImageView; private Rec
為頁內的tab新增的iframe新增載入動畫過渡效果
var iframe = $("iframe[data-id=" + id + " ]"); if (iframe.length > 0) { var exist = $(iframe[0]).attr("exist");