您的位置:首页 > 大数据 > 人工智能

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

2016-12-30 13:37 961 查看
1.首先描述下自定义控件的一般方法:

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

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

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

MainActivity:

[java] view
plain copy







public class MainActivity extends Activity {

private GifView gv;

private ListView lv_content;

private int[] gifResource={R.drawable.car,R.drawable.rick,R.drawable.car,R.drawable.mm,R.drawable.qq};

private MyAdapter adapter=null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

lv_content=(ListView) findViewById(R.id.lv_content);

adapter = new MyAdapter();

lv_content.setAdapter(adapter);

/*

lv_content.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

if(adapter!=null)

{

adapter.notifyDataSetChanged();

}

}

});*/

// 去掉listView的item点击的效果

// lv_content.setEnabled(false);

lv_content.setSelector(color.transparent);

}

private class MyAdapter extends BaseAdapter{

@Override

public int getCount() {

// TODO Auto-generated method stub

return gifResource.length;

}

@Override

public Object getItem(int position) {

return null;

}

@Override

public long getItemId(int position) {

return 0;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder=null;

if(convertView == null)

{

convertView=View.inflate(getApplicationContext(), R.layout.item_gif, null);

holder=new ViewHolder();

holder.tv_username=(TextView) convertView.findViewById(R.id.tv_username);

holder.tv_comemnt=(TextView) convertView.findViewById(R.id.tv_comment);

holder.gv=(GifView) convertView.findViewById(R.id.gv);

convertView.setTag(holder);

}else{

holder=(ViewHolder) convertView.getTag();

}

holder.tv_username.setText("username"+position);

holder.tv_comemnt.setText("comment"+position);

holder.gv.setMovieResource(gifResource[position]);

holder.gv.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

GifView view=(GifView) v;

view.setPaused(!view.isPause());

}

});

return convertView;

}

class ViewHolder{

public TextView tv_username;

public TextView tv_comemnt;

public GifView gv;

}

}

}

自定义组件GifView:

[java] view
plain copy







package com.example.gifdemo.view;

import com.example.gifdemo.R;

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Movie;

import android.os.Build;

import android.os.SystemClock;

import android.util.AttributeSet;

import android.view.View;

/**使用Android自定义的movie实现**/

public class GifView extends View{

private static final int DEFAULT_GIF_DURATION=1000;

// the reference for gif

private int mMovieResourceId;

private Movie mMovie;

private long mStart;

private int mCurrentAnimationTime=0;

private boolean mPause=true;

private boolean mVisible=true;

private long mWidth;

private long mHeight;

private float mScale;

private float mLeft;

private float mTop;

private int mMeasuredWidth;

private int mMeasureHeight;

public GifView(Context context) {

this(context,null);

}

public GifView(Context context, AttributeSet attrs) {

this(context, attrs,R.styleable.CustomTheme_gifMoviewViewStyle);

}

public GifView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setViewAttributes(context, attrs, defStyleAttr);

}

private void setViewAttributes(Context context, AttributeSet attrs, int defStyleAttr)

{

/**

* Starting from HONEYCOMB have to turn off HW acceleration to draw

* Movie on Canvas.

*/

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)

{

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

}

//?? TODO get the collection of the attrs

final TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.GifView, defStyleAttr, R.style.Widget_GifMoviewView);

mPause=array.getBoolean(R.styleable.GifView_paused, true);

mMovieResourceId=array.getResourceId(R.styleable.GifView_gif, -1);

// recycle TypedArray

array.recycle();

if(mMovieResourceId!=-1)

{

mMovie=Movie.decodeStream(getResources().openRawResource(mMovieResourceId));

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

if(mMovie!=null)

{

int mWidth=mMovie.width();

int mHeight=mMovie.height();

float scaleX=1f;

int measureModeWidth=MeasureSpec.getMode(widthMeasureSpec);

if(measureModeWidth!=MeasureSpec.UNSPECIFIED)

{

int maximumWidth=MeasureSpec.getSize(widthMeasureSpec);

if(mWidth>maximumWidth)

{

scaleX=(float)mWidth/(float)maximumWidth;

}

}

float scaleY=1f;

int measureModeHeight=MeasureSpec.getMode(heightMeasureSpec);

if(measureModeHeight!=MeasureSpec.UNSPECIFIED)

{

int maximumHeight=MeasureSpec.getSize(heightMeasureSpec);

if(mHeight>maximumHeight)

{

scaleY=(float)mHeight/(float)maximumHeight;

}

}

mScale=1f/Math.max(scaleX, scaleY);

mMeasuredWidth=(int) (mWidth*mScale);

mMeasureHeight=(int) (mHeight*mScale);

setMeasuredDimension(mMeasuredWidth,mMeasureHeight);

}else

{

setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());

}

}

@Override

protected void onLayout(boolean changed, int left, int top, int right,

int bottom) {

super.onLayout(changed, left, top, right, bottom);

/** Calculate left / top for drawing in center **/

mLeft=(getWidth()-mMeasuredWidth)/2f;

mTop=(getHeight()-mMeasureHeight)/2f;

mVisible= getVisibility() == View.VISIBLE;

}

@Override

protected void onDraw(Canvas canvas) {

if(mMovie!=null)

{

if(!mPause)

{

updateCurrentTime();

drawFrame(canvas);

invalidateView();

}else{

drawFrame(canvas);

}

}

}

private void updateCurrentTime()

{

long now=SystemClock.uptimeMillis();

if(mStart==0)

{

mStart=now;

}

int dur=mMovie.duration();

if(dur==0)

{

dur=DEFAULT_GIF_DURATION;

}

mCurrentAnimationTime=(int)((now-mStart)%dur);

}

private void drawFrame(Canvas canvas)

{

mMovie.setTime(mCurrentAnimationTime);

canvas.save(Canvas.MATRIX_SAVE_FLAG);

canvas.scale(mScale, mScale);

// TODO

mMovie.draw(canvas, mLeft/mScale, mTop/mScale);

mMovie.draw(canvas, 0, 0);

canvas.restore();

}

/**

* Invalidates view only if it is visible.

* <br>

* {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher.

*

*/

@SuppressLint("NewApi")

private void invalidateView() {

if(mVisible) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {

postInvalidateOnAnimation();

} else {

invalidate();

}

}

}

// the methods of the important attribute

public void setPaused(boolean pause)

{

this.mPause=pause;

// retrieve the StartTime

if(!mPause)

{

mStart=SystemClock.uptimeMillis()-mCurrentAnimationTime;

}

invalidate();

}

public boolean isPause()

{

return mPause;

}

public void setMovieResource(int movieResourceId)

{

this.mMovieResourceId=movieResourceId;

mMovie=Movie.decodeStream(getResources().openRawResource(movieResourceId));

// important Call this when something has changed which has invalidated the

//layout of this view.

requestLayout();

}

public void setMovie(Movie movie)

{

this.mMovie=movie;

requestLayout();

}

public Movie getMovie()

{

return mMovie;

}

public void setMovieTime(int time)

{

this.mCurrentAnimationTime=time;

invalidate();

}

}

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

自定义TextView:

[java] view
plain copy







package com.yyg.gifdemo3.view;

public class MyTextView extends TextView{

private Context mContext;

private SpannableStringBuilder mSb=new SpannableStringBuilder();

private String dummyStr="dummy";

private SimpleImageMemCache mCache;

private List<AnimatedImageSpan> mGifSpanList=new ArrayList<AnimatedImageSpan>();

public MyTextView(Context context) {

super(context);

mContext=context;

}

public MyTextView(Context context, AttributeSet attrs) {

super(context, attrs);

mContext=context;

}

public MyTextView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

mContext=context;

}

public void setImageCache(SimpleImageMemCache pImageCache)

{

this.mCache=pImageCache;

}

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

Log.d(this.getClass().getName(), "onDetachedFromWindow ");

for (AnimatedImageSpan ais : mGifSpanList) {

Log.d(this.getClass().getName(), "animation playing " + ais.isPlaying());

if (ais.isPlaying()) {

ais.stopRendering();

}

}

mGifSpanList.clear();

mSb.clearSpans();

mSb.clear();

}

public void appendText(String text)

{

mSb.append(text);

}

public void appendAnimation(GifResource pAssetsSet,AnimationSettings pSettings)

{

mSb.append(dummyStr);

AnimatedImageSpan ais=new AnimatedImageSpan(mContext);

ais.setAssetsSet(pAssetsSet);

ais.setBitmapCache(mCache);

mSb.setSpan(ais, mSb.length()-dummyStr.length(), mSb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

AnimationClickableSpan clickableSpan=new AnimationClickableSpan(this, ais, pSettings);

mSb.setSpan(clickableSpan, mSb.length()-dummyStr.length(), mSb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

mGifSpanList.add(ais);

}

public void finishAddContent()

{

this.setText(mSb);

// setMovementMethod,此方法在需要响应用户事件时使用,如点击一个电话号码就跳转到拨号页面。如果不执行这个方法是不会响应事件的,即便文本看着已经是下划线蓝色字了。

this.setMovementMethod(LinkMovementMethod.getInstance());

}

private static class AnimationClickableSpan extends ClickableSpan

{

private AnimatedImageSpan mImageSpan;

private AnimationSettings mSettings;

private AnimatedImageUpdateHandler updateHandler;

public AnimationClickableSpan(MyTextView pTextView ,AnimatedImageSpan pAnimatedImageSpan,AnimationSettings pSettings)

{

this.mImageSpan=pAnimatedImageSpan;

this.mSettings=pSettings;

this.updateHandler=new AnimatedImageUpdateHandler(pTextView);

}

@Override

public void onClick(View widget) {

if(this.mImageSpan.isPlaying())

{

this.mImageSpan.stopRendering();

}else{

this.mImageSpan.playGif(this.mSettings,this.updateHandler);

}

}

}

}

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

(3)使用WebView加载Gif:

[java] view
plain copy







package com.example.gifdemo3;

import android.os.Build;

import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

import android.webkit.WebView;

public class MainActivity extends Activity {

private WebView wv_gif;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

wv_gif=(WebView) findViewById(R.id.wv_gif);

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT)

{

wv_gif.loadUrl("http://www.wyzu.cn/data/uploadfile/200803/2008032812262650.gif");

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gif
相关文章推荐