1.首先描述下自定义控件的一般方法: 自定义控件是被创造出来,所以先要复写它三个的构造方法,根据需求决定复写哪个,若没有自定义属性,复写只有一个参数的即可。若有自定义属性,则可以通过obtainSty

来源:互联网 发布:常用数字图像处理算法 编辑:程序博客网 时间:2024/04/30 15:51

1.首先描述下自定义控件的一般方法:

自定义控件是被创造出来,所以先要复写它三个的构造方法,根据需求决定复写哪个,若没有自定义属性,复写只有一个参数的即可。若有自定义属性,则可以通过obtainStyledAttributes获得TypedArray对象,通过该对象获得属性并进行相应操作。然后下面的过程和画画差不多,我们在画一样东西的时候,首先要知道物品大概的样子,也就是需要复写onMeasure()方法,测量控件以及其子布局的大小。知道物品的大概后,我们需要对其里面的细节精雕细琢,也就是调用onLayout()方法,决定其子View的位置。最后就是将图整体勾勒出来,即是调用onDraw()方法。这样子控件大概的样子就出来了,再根据需求增加相应借口,回调方法。

2.Android显示gif的三种方式:

(1)使用Android自带的Movie对象,将Gif当成视频。随着时间的变化,通过setTime方法设置需要显示的图片,然后onDraw方法不断将新的画画出来。实例代码如下:

MainActivity:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends Activity {  
  2.   
  3.       
  4.     private GifView gv;  
  5.     private ListView lv_content;  
  6.     private int[] gifResource={R.drawable.car,R.drawable.rick,R.drawable.car,R.drawable.mm,R.drawable.qq};  
  7.     private MyAdapter adapter=null;  
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.           
  13.         lv_content=(ListView) findViewById(R.id.lv_content);  
  14.   
  15.         adapter = new MyAdapter();  
  16.         lv_content.setAdapter(adapter);  
  17.     /*   
  18.         lv_content.setOnItemClickListener(new OnItemClickListener() { 
  19.  
  20.             @Override 
  21.             public void onItemClick(AdapterView<?> parent, View view, 
  22.                     int position, long id) { 
  23.                  
  24.                 if(adapter!=null) 
  25.                 { 
  26.                     adapter.notifyDataSetChanged(); 
  27.                 } 
  28.             } 
  29.         });*/  
  30.       
  31.         // 去掉listView的item点击的效果  
  32. //      lv_content.setEnabled(false);  
  33.         lv_content.setSelector(color.transparent);  
  34.     }  
  35.       
  36.       
  37.     private class MyAdapter extends BaseAdapter{  
  38.   
  39.         @Override  
  40.         public int getCount() {  
  41.             // TODO Auto-generated method stub  
  42.             return gifResource.length;  
  43.         }  
  44.   
  45.         @Override  
  46.         public Object getItem(int position) {  
  47.             return null;  
  48.         }  
  49.   
  50.         @Override  
  51.         public long getItemId(int position) {  
  52.             return 0;  
  53.         }  
  54.   
  55.         @Override  
  56.         public View getView(int position, View convertView, ViewGroup parent) {  
  57.               
  58.             ViewHolder holder=null;  
  59.             if(convertView == null)  
  60.             {  
  61.                 convertView=View.inflate(getApplicationContext(), R.layout.item_gif, null);  
  62.                 holder=new ViewHolder();  
  63.                 holder.tv_username=(TextView) convertView.findViewById(R.id.tv_username);  
  64.                 holder.tv_comemnt=(TextView) convertView.findViewById(R.id.tv_comment);  
  65.                 holder.gv=(GifView) convertView.findViewById(R.id.gv);  
  66.                   
  67.                 convertView.setTag(holder);  
  68.             }else{  
  69.                   
  70.                 holder=(ViewHolder) convertView.getTag();  
  71.             }  
  72.               
  73.             holder.tv_username.setText("username"+position);  
  74.             holder.tv_comemnt.setText("comment"+position);  
  75.             holder.gv.setMovieResource(gifResource[position]);  
  76.               
  77.             holder.gv.setOnClickListener(new OnClickListener() {  
  78.                   
  79.                 @Override  
  80.                 public void onClick(View v) {  
  81.                     GifView view=(GifView) v;  
  82.                     view.setPaused(!view.isPause());  
  83.                 }  
  84.             });  
  85.               
  86.             return convertView;  
  87.         }  
  88.           
  89.           
  90.         class ViewHolder{  
  91.               
  92.             public TextView tv_username;  
  93.             public TextView tv_comemnt;  
  94.             public GifView gv;  
  95.               
  96.               
  97.         }  
  98.           
  99.     }  
  100.   
  101.       
  102.       
  103. }  

自定义组件GifView:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.gifdemo.view;  
  2.   
  3. import com.example.gifdemo.R;  
  4.   
  5. import android.annotation.SuppressLint;  
  6. import android.content.Context;  
  7. import android.content.res.TypedArray;  
  8. import android.graphics.Canvas;  
  9. import android.graphics.Movie;  
  10. import android.os.Build;  
  11. import android.os.SystemClock;  
  12. import android.util.AttributeSet;  
  13. import android.view.View;  
  14.   
  15.   
  16. /**使用Android自定义的movie实现**/  
  17.   
  18. public class GifView extends View{  
  19.   
  20.       
  21.     private static final int DEFAULT_GIF_DURATION=1000;  
  22.     // the reference for gif  
  23.     private int mMovieResourceId;  
  24.     private Movie mMovie;  
  25.       
  26.       
  27.     private long mStart;  
  28.     private int mCurrentAnimationTime=0;  
  29.       
  30.     private boolean mPause=true;  
  31.     private boolean mVisible=true;  
  32.       
  33.       
  34.     private long mWidth;  
  35.     private long mHeight;  
  36.       
  37.     private float mScale;  
  38.       
  39.     private float mLeft;  
  40.     private float mTop;  
  41.       
  42.     private int mMeasuredWidth;  
  43.     private int mMeasureHeight;  
  44.       
  45.     public GifView(Context context) {  
  46.         this(context,null);  
  47.     }  
  48.       
  49.       
  50.     public GifView(Context context, AttributeSet attrs) {  
  51.         this(context, attrs,R.styleable.CustomTheme_gifMoviewViewStyle);  
  52.     }  
  53.       
  54.       
  55.     public GifView(Context context, AttributeSet attrs, int defStyleAttr) {  
  56.         super(context, attrs, defStyleAttr);  
  57.         setViewAttributes(context, attrs, defStyleAttr);  
  58.     }  
  59.       
  60.       
  61.     private void setViewAttributes(Context context, AttributeSet attrs, int defStyleAttr)  
  62.     {  
  63.           
  64.         /** 
  65.          * Starting from HONEYCOMB have to turn off HW acceleration to draw 
  66.          * Movie on Canvas. 
  67.          */  
  68.         if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)  
  69.         {  
  70.             setLayerType(View.LAYER_TYPE_SOFTWARE, null);  
  71.         }  
  72.           
  73.         //?? TODO get the collection of the attrs  
  74.         final TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.GifView, defStyleAttr, R.style.Widget_GifMoviewView);  
  75.           
  76.         mPause=array.getBoolean(R.styleable.GifView_paused, true);  
  77.         mMovieResourceId=array.getResourceId(R.styleable.GifView_gif, -1);  
  78.           
  79.         // recycle TypedArray  
  80.         array.recycle();  
  81.           
  82.         if(mMovieResourceId!=-1)  
  83.         {  
  84.             mMovie=Movie.decodeStream(getResources().openRawResource(mMovieResourceId));  
  85.         }  
  86.           
  87.     }  
  88.       
  89.       
  90.     @Override  
  91.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  92.           
  93.         if(mMovie!=null)  
  94.         {  
  95.               
  96.             int mWidth=mMovie.width();  
  97.             int mHeight=mMovie.height();  
  98.               
  99.           
  100.         float scaleX=1f;  
  101.         int measureModeWidth=MeasureSpec.getMode(widthMeasureSpec);  
  102.         if(measureModeWidth!=MeasureSpec.UNSPECIFIED)  
  103.         {  
  104.             int maximumWidth=MeasureSpec.getSize(widthMeasureSpec);  
  105.             if(mWidth>maximumWidth)  
  106.             {  
  107.                 scaleX=(float)mWidth/(float)maximumWidth;  
  108.             }  
  109.         }  
  110.           
  111.           
  112.         float scaleY=1f;  
  113.         int measureModeHeight=MeasureSpec.getMode(heightMeasureSpec);  
  114.         if(measureModeHeight!=MeasureSpec.UNSPECIFIED)  
  115.         {  
  116.             int maximumHeight=MeasureSpec.getSize(heightMeasureSpec);  
  117.             if(mHeight>maximumHeight)  
  118.             {  
  119.                 scaleY=(float)mHeight/(float)maximumHeight;  
  120.             }  
  121.         }  
  122.           
  123.           
  124.         mScale=1f/Math.max(scaleX, scaleY);  
  125.           
  126.         mMeasuredWidth=(int) (mWidth*mScale);  
  127.         mMeasureHeight=(int) (mHeight*mScale);  
  128.           
  129.         setMeasuredDimension(mMeasuredWidth,mMeasureHeight);  
  130.         }else  
  131.         {  
  132.             setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());  
  133.               
  134.         }  
  135.           
  136.     }  
  137.       
  138.       
  139.       
  140.     @Override  
  141.     protected void onLayout(boolean changed, int left, int top, int right,  
  142.             int bottom) {  
  143.         super.onLayout(changed, left, top, right, bottom);  
  144.           
  145.         /** Calculate left / top for drawing in center **/  
  146.           
  147.         mLeft=(getWidth()-mMeasuredWidth)/2f;  
  148.         mTop=(getHeight()-mMeasureHeight)/2f;  
  149.           
  150.         mVisible= getVisibility() == View.VISIBLE;  
  151.     }  
  152.       
  153.       
  154.     @Override  
  155.     protected void onDraw(Canvas canvas) {  
  156.           
  157.         if(mMovie!=null)  
  158.         {  
  159.               
  160.             if(!mPause)  
  161.             {  
  162.                 updateCurrentTime();  
  163.                 drawFrame(canvas);  
  164.                 invalidateView();  
  165.             }else{  
  166.                   
  167.                 drawFrame(canvas);  
  168.             }  
  169.               
  170.         }  
  171.     }  
  172.       
  173.       
  174.     private void updateCurrentTime()  
  175.     {  
  176.         long now=SystemClock.uptimeMillis();  
  177.         if(mStart==0)  
  178.         {  
  179.             mStart=now;  
  180.         }  
  181.           
  182.         int dur=mMovie.duration();  
  183.         if(dur==0)  
  184.         {  
  185.             dur=DEFAULT_GIF_DURATION;  
  186.         }  
  187.           
  188.         mCurrentAnimationTime=(int)((now-mStart)%dur);  
  189.           
  190.     }  
  191.       
  192.     private void drawFrame(Canvas canvas)  
  193.     {  
  194.           
  195.         mMovie.setTime(mCurrentAnimationTime);  
  196.         canvas.save(Canvas.MATRIX_SAVE_FLAG);  
  197.         canvas.scale(mScale, mScale);  
  198.         // TODO  
  199.         mMovie.draw(canvas, mLeft/mScale, mTop/mScale);  
  200.         mMovie.draw(canvas, 00);  
  201.         canvas.restore();  
  202.     }  
  203.       
  204.       
  205.     /** 
  206.      * Invalidates view only if it is visible. 
  207.      * <br> 
  208.      * {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher. 
  209.      *  
  210.      */  
  211.     @SuppressLint("NewApi")  
  212.     private void invalidateView() {  
  213.         if(mVisible) {  
  214.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {  
  215.                 postInvalidateOnAnimation();  
  216.             } else {  
  217.                 invalidate();  
  218.             }  
  219.         }  
  220.     }  
  221.       
  222.       
  223.       
  224.     // the methods of the important attribute  
  225.     public void setPaused(boolean pause)  
  226.     {  
  227.         this.mPause=pause;  
  228.           
  229.         // retrieve the StartTime  
  230.         if(!mPause)  
  231.         {  
  232.             mStart=SystemClock.uptimeMillis()-mCurrentAnimationTime;  
  233.         }  
  234.           
  235.         invalidate();  
  236.     }  
  237.       
  238.       
  239.     public boolean isPause()  
  240.     {  
  241.         return mPause;  
  242.     }  
  243.       
  244.       
  245.     public void setMovieResource(int movieResourceId)  
  246.     {  
  247.         this.mMovieResourceId=movieResourceId;  
  248.         mMovie=Movie.decodeStream(getResources().openRawResource(movieResourceId));  
  249.         // important Call this when something has changed which has invalidated the  
  250.         //layout of this view.   
  251.         requestLayout();  
  252.     }  
  253.       
  254.     public void setMovie(Movie movie)  
  255.     {  
  256.         this.mMovie=movie;  
  257.         requestLayout();  
  258.     }  
  259.       
  260.       
  261.     public Movie getMovie()  
  262.     {  
  263.         return mMovie;  
  264.     }  
  265.       
  266.       
  267.     public void setMovieTime(int time)  
  268.     {  
  269.         this.mCurrentAnimationTime=time;  
  270.         invalidate();  
  271.     }  
  272. }  


(2)自定义TextView显示Gif,先使用GifDecoder将Gif文件解析成一张张图片,然后通过ImageSpan将图片显示在TextView中,定义一个线程不断刷新图片。


自定义TextView:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.yyg.gifdemo3.view;  
  2.   
  3. public class MyTextView extends TextView{  
  4.   
  5.     private Context mContext;  
  6.     private SpannableStringBuilder mSb=new SpannableStringBuilder();  
  7.     private String dummyStr="dummy";  
  8.     private SimpleImageMemCache mCache;  
  9.     private List<AnimatedImageSpan> mGifSpanList=new ArrayList<AnimatedImageSpan>();  
  10.       
  11.       
  12.     public MyTextView(Context context) {  
  13.         super(context);  
  14.         mContext=context;  
  15.     }  
  16.       
  17.     public MyTextView(Context context, AttributeSet attrs) {  
  18.         super(context, attrs);  
  19.         mContext=context;  
  20.           
  21.     }     
  22.       
  23.     public MyTextView(Context context, AttributeSet attrs, int defStyle) {  
  24.         super(context, attrs, defStyle);  
  25.         mContext=context;  
  26.     }  
  27.       
  28.     public void setImageCache(SimpleImageMemCache pImageCache)  
  29.     {  
  30.         this.mCache=pImageCache;  
  31.     }  
  32.       
  33.       
  34.       
  35.     @Override  
  36.     protected void onDetachedFromWindow() {  
  37.         super.onDetachedFromWindow();  
  38.         Log.d(this.getClass().getName(), "onDetachedFromWindow ");  
  39.         for (AnimatedImageSpan ais : mGifSpanList) {  
  40.             Log.d(this.getClass().getName(), "animation playing " + ais.isPlaying());  
  41.             if (ais.isPlaying()) {  
  42.                 ais.stopRendering();  
  43.             }  
  44.         }  
  45.         mGifSpanList.clear();  
  46.         mSb.clearSpans();  
  47.         mSb.clear();  
  48.     }  
  49.       
  50.   
  51.     public void appendText(String text)  
  52.     {  
  53.         mSb.append(text);  
  54.     }  
  55.     public void appendAnimation(GifResource pAssetsSet,AnimationSettings pSettings)  
  56.     {  
  57.         mSb.append(dummyStr);  
  58.         AnimatedImageSpan ais=new AnimatedImageSpan(mContext);  
  59.         ais.setAssetsSet(pAssetsSet);  
  60.         ais.setBitmapCache(mCache);  
  61.         mSb.setSpan(ais, mSb.length()-dummyStr.length(), mSb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  62.         AnimationClickableSpan clickableSpan=new AnimationClickableSpan(this, ais, pSettings);  
  63.         mSb.setSpan(clickableSpan, mSb.length()-dummyStr.length(), mSb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  64.         mGifSpanList.add(ais);  
  65.     }  
  66.       
  67.     public void finishAddContent()  
  68.     {  
  69.         this.setText(mSb);  
  70.         // setMovementMethod,此方法在需要响应用户事件时使用,如点击一个电话号码就跳转到拨号页面。如果不执行这个方法是不会响应事件的,即便文本看着已经是下划线蓝色字了。  
  71.         this.setMovementMethod(LinkMovementMethod.getInstance());  
  72.     }  
  73.       
  74.     private static class AnimationClickableSpan extends ClickableSpan  
  75.     {  
  76.         private AnimatedImageSpan mImageSpan;  
  77.         private AnimationSettings mSettings;  
  78.         private AnimatedImageUpdateHandler updateHandler;  
  79.           
  80.           
  81.         public AnimationClickableSpan(MyTextView pTextView ,AnimatedImageSpan pAnimatedImageSpan,AnimationSettings pSettings)  
  82.         {  
  83.             this.mImageSpan=pAnimatedImageSpan;  
  84.             this.mSettings=pSettings;  
  85.             this.updateHandler=new AnimatedImageUpdateHandler(pTextView);  
  86.         }  
  87.   
  88.         @Override  
  89.         public void onClick(View widget) {  
  90.               
  91.             if(this.mImageSpan.isPlaying())  
  92.             {  
  93.                 this.mImageSpan.stopRendering();  
  94.             }else{  
  95.                   
  96.                 this.mImageSpan.playGif(this.mSettings,this.updateHandler);  
  97.             }  
  98.         }  
  99.           
  100.     }  
  101.       
  102. }  


完整项目链接:http://download.csdn.net/detail/aehaojiu/8438351

(3)使用WebView加载Gif

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.gifdemo3;  
  2.   
  3.   
  4. import android.os.Build;  
  5. import android.os.Bundle;  
  6. import android.app.Activity;  
  7. import android.view.Menu;  
  8. import android.webkit.WebView;  
  9.   
  10.   
  11. public class MainActivity extends Activity {  
  12.   
  13.   
  14.     private WebView wv_gif;  
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.           
  20.         wv_gif=(WebView) findViewById(R.id.wv_gif);  
  21.           
  22.         if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT)  
  23.         {  
  24.               
  25.             wv_gif.loadUrl("http://www.wyzu.cn/data/uploadfile/200803/2008032812262650.gif");  
  26.         }  
  27.     }  
  28.   
  29.   
  30.   
  31.   
  32.   
  33.   
  34. }  

1 0
原创粉丝点击