GVKun编程网logo

android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?(android listview baseadapter)

7

在本文中,我们将带你了解android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?在这篇文章中,我们将为您详细介绍android-ListAdapt

在本文中,我们将带你了解android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?在这篇文章中,我们将为您详细介绍android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?的方方面面,并解答android listview baseadapter常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的Android AdapterViewAnimator、Android AdapterViewAnimator控件、Android Animation 之 ViewAnimator\ViewFlipper、Android ImageView setImageBitmap 不显示图片

本文目录一览:

android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?(android listview baseadapter)

android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?(android listview baseadapter)

我有一个列表适配器,其中图像加载有旋转进度动画,直到从网上获取它们为止.当我在listView中向下滚动时,似乎动画旋转了上一张图像…这是一个非常奇怪且令人讨厌的效果.唯一应该旋转的是进度动画.

我使用一个称为ImageLoader的类来异步netfetch图像:

final int stub_id=R.drawable.progress;
public void displayImage(String url, Activity activity, ImageView imageView,int size)
{
    //Log.d("ImageLoader" , url);
    this.size=size;
    if(cache.containsKey(url)) {
        //If this works, then why do the OLD images still spin??
                    imageView.clearanimation();
        //imageView.setBackgroundDrawable(null);
        //imageView.setimageDrawable(null);
        imageView.setimageBitmap(cache.get(url));
    }
    else
    {
        rotation = AnimationUtils.loadAnimation(activity, R.drawable.progress);
        rotation.setRepeatCount(Animation.INFINITE);
        imageView.startAnimation(rotation);
        queuePhoto(url, activity, imageView);
        //imageView.setimageResource(stub_id);
        //imageView.setBackgroundResource(stub_id); 
    }
    Resources r = activity.getResources();
    int dip = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, r.getdisplayMetrics());
    LayoutParams layoutParams = imageView.getLayoutParams();
    layoutParams.height = dip;
    layoutParams.width = dip;
    imageView.setLayoutParams(layoutParams);
}

现在您可能会问,queuePhoto是做什么的?这是动画开始的唯一其他地方.

//Used to display bitmap in the UI thread
class Bitmapdisplayer implements Runnable
{
    Bitmap bitmap;
    ImageView imageView;
    public Bitmapdisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
    public void run()
    {


        if(bitmap!=null) {
            imageView.clearanimation();
            imageView.setimageBitmap(bitmap);
        }
        else {
            imageView.clearanimation();
            rotation = AnimationUtils.loadAnimation(context, R.drawable.progress);
            rotation.setRepeatCount(Animation.INFINITE);
            imageView.startAnimation(rotation);
            //imageView.setimageResource(stub_id);

        }
    }
}

现在,我的列表适配器的getView的一部分:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if( convertView == null ){
            vi = inflater.inflate(R.layout.trending_item, null);
            holder=new ViewHolder();
            holder.img1 = (ImageView) vi.findViewById(R.id.t_item_1);
            holder.img2 = (ImageView) vi.findViewById(R.id.t_item_2);
            holder.img3 = (ImageView) vi.findViewById(R.id.t_item_3);
            vi.setTag(holder);
        } else {
            holder=(ViewHolder)vi.getTag();
        }
        JSONObject t1= ts.get(1);
        if(t1 !=null) {
                holder.img1.setTag(t1.getString("image_small"));
                imageLoader.displayImage(t1.getString("image_small"), act, holder.img1,IMAGE_SIZE);
                holder.img1.setTag(TAG_T t1.getString("id"));
                holder.img1.setonClickListener(ocl);
            } else {
                holder.img1.setimageDrawable(null);
                holder.img1.setBackgroundDrawable(null);    
                holder.img1.setTag(null);   
                holder.img1.setTag(TAG_T, null);
            }

更新

我实现了JBM提出的解决方案,但是我无法使其工作,他建议在UI线程上运行.

public class RemoteImageView extends ImageView implements RemoteLoadListener {

final int stub_id=R.drawable.progress;
int size;
private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();
Animation rotation;
private File cacheDir;


public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

public RemoteImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    //Make the background thead low priority. This way it will not affect the UI performance
    photoLoaderThread.setPriority(Thread.norM_PRIORITY-1);

    //Find the dir to save cached images
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),context.getString(R.string.app_name));
    else
        cacheDir=context.getCacheDir();
    if(!cacheDir.exists())
        cacheDir.mkdirs();
}

public RemoteImageView(Context context) {
    super(context);

}

public void displayRemoteImage(String url, Activity activity, int size)
{
    this.myUrl = url;
    this.size=size;
    Resources r = activity.getResources();
    int dip = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, r.getdisplayMetrics());
    LayoutParams layoutParams = this.getLayoutParams();
    layoutParams.height = dip;
    layoutParams.width = dip;
    this.setLayoutParams(layoutParams);
    if(cache.containsKey(url)) {
        this.clearanimation();
        setimageBitmap(cache.get(url));
    }
    else
    {
        rotation = AnimationUtils.loadAnimation(activity, R.drawable.progress);
        rotation.setRepeatCount(Animation.INFINITE);
        this.startAnimation(rotation);
        queuePhoto(url, activity, this);
    }
}

@Override
public void onl oadSuccess(String url, Bitmap bmp) {
    if (url.equals(myUrl)) {
        setimageBitmap(bmp);
    } else {
        /* the arrived bitmap is stale. do nothing. */
    }
}

@Override
public void onl oadFail(String url) {
    if (url.equals(myUrl)) {
        setimageBitmap(((BitmapDrawable)getResources().getDrawable(stub_id)).getBitmap());
    } else {
        /* the Failed bitmap is stale. do nothing. */
    }
}
String myUrl;
private void queuePhoto(String url, Activity activity, ImageView imageView)
{
    //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
    photosQueue.Clean(imageView);
    PhotoToLoad p=new PhotoToLoad(url, imageView);
    synchronized(photosQueue.photosToLoad){
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }

    //start thread if it's not started yet
    if(photoLoaderThread.getState()==Thread.State.NEW)
        photoLoaderThread.start();
}
PhotosQueue photosQueue=new PhotosQueue();

public void stopThread()
{
    photoLoaderThread.interrupt();
}

//stores list of photos to download
class PhotosQueue
{
    private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();

    //removes all instances of this ImageView
    public void Clean(ImageView image)
    {
        for(int j=0 ;j<photosToLoad.size();){
            if(photosToLoad.get(j).imageView==image)
                photosToLoad.remove(j);
            else
                ++j;
        }
    }
}

//Task for the queue
private class PhotoToLoad
{
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i){
        url=u; 
        imageView=i;
    }
}


class Photosloader extends Thread {
    public void run() {
        try {
            while(true)
            {
                //thread waits until there are any images to load in the queue
                if(photosQueue.photosToLoad.size()==0)
                    synchronized(photosQueue.photosToLoad){
                        photosQueue.photosToLoad.wait();
                    }
                if(photosQueue.photosToLoad.size()!=0)
                {
                    PhotoToLoad photoToLoad;
                    synchronized(photosQueue.photosToLoad){
                        photoToLoad=photosQueue.photosToLoad.pop();
                    }
                    Bitmap bmp=getBitmap(photoToLoad.url);
                    cache.put(photoToLoad.url, bmp);
                    Object tag=photoToLoad.imageView.getTag();
                    if(tag!=null && ((String)tag).equals(photoToLoad.url)){
                        Bitmapdisplayer bd=new Bitmapdisplayer(bmp, photoToLoad.imageView);
                        Activity a=(Activity)photoToLoad.imageView.getContext();
                        a.runOnUiThread(bd);
                    }
                }
                if(Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {
            //allow thread to exit
        }
    }
}

Photosloader photoLoaderThread=new Photosloader();

//Used to display bitmap in the UI thread
class Bitmapdisplayer implements Runnable
{
    Bitmap bitmap;
    ImageView imageView;
    public Bitmapdisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
    public void run()
    {   
        if(bitmap!=null) {
            imageView.clearanimation();
            imageView.setimageBitmap(bitmap);
        }
        else {
            imageView.clearanimation();
            imageView.setimageResource(stub_id);
        }
    }
}
private Bitmap getBitmap(String url) 
{
    System.out.println("GET: " +url);
    if(url== null) {
        return null;
    }
    //I identify images by hashcode. Not a perfect solution, good for the demo.
    String filename=String.valueOf(url.hashCode());
    File f=new File(cacheDir, filename);

    //from SD cache
    Bitmap b = decodeFile(f);
    if(b!=null)
        return b;

    //from web
    try {
        Bitmap bitmap=null;
        InputStream is=new URL(url).openStream();
        OutputStream os = new FileOutputStream(f);
        Utils.copyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex){
        ex.printstacktrace();
        return null;
    }
}

//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
    try {
        //decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //Find the correct scale value. It should be the power of 2.

        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<size || height_tmp/2<size)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale*=2;
        }

        //decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
        Log.d("ImageLoader",e.getMessage(),e);
    }
    return null;
}

}

解决方法:

这里的问题是ImageView与displayImage函数之间的竞争.当列表向上或向下滚动时,行将被重用,因此,当远程映像到达时,通常会发生其目标视图已经属于另一行的情况.唯一可靠的方法是让您拥有自己的类RemoteImageView来扩展ImageView,该ImageView可在内部处理图像.然后,RemoteImageView可以进行适当的同步.

让您的queuePhoto方法采用RemoteLoadListener代替ImageView,如下所示:

public interface RemoteLoadListener {
    void onl oadFail(String url);
    void onl oadSuccess(String url, Bitmap bmp);
}

然后将RemoteImageView设置为RemoteLoadListener并在内部执行所有操作:

public class RemoteImageView extends ImageView implements RemoteLoadListener {

    final int static stub_id=R.drawable.progress;
    public void displayImage(String url, Activity activity, int size)
    {
        myUrl = url;

        if(cache.containsKey(url)) {
            ...
            setimageBitmap(cache.get(url));
        }
        else
        {
            ...
            imageView.startAnimation(rotation);
            queuePhoto(url, activity, this);
        }
    }

    @Override
    public void onl oadSuccess(String url, Bitmap bmp) {
        if (url.equals(myUrl)) {
            setimageBitmap(bmp);
        } else {
            /* the arrived bitmap is stale. do nothing. */
        }
    }

    @Override
    public void onl oadFail(String url) {
        if (url.equals(myUrl)) {
            setimageBitmap(placeholder);
        } else {
            /* the Failed bitmap is stale. do nothing. */
        }
    }
}

因此,在您的getView方法中,您只需执行以下操作:

holder.img1.displayImage(t1.getString("image_small"), act, IMAGE_SIZE);

更新

首先尝试降低系统的复杂性.我已经删除了您的照片队列和缓存,并将其替换为从Web上下载图像(此部分基于您的代码).我没有运行这段代码,只是输入了它.但这应该给您一个清晰的想法.

public class RemoteImageView extends ImageView implements RemoteLoadListener {

    public RemoteImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RemoteImageView(Context context) {
        super(context);

    }

    public void displayRemoteImage(String url, Activity activity, int size)
    {
        this.myUrl = url;
        this.size=size;
        Resources r = activity.getResources();
        int dip = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, r.getdisplayMetrics());
        LayoutParams layoutParams = this.getLayoutParams();
        layoutParams.height = dip;
        layoutParams.width = dip;
        this.setLayoutParams(layoutParams);

        {
            rotation = AnimationUtils.loadAnimation(activity, R.drawable.progress);
            rotation.setRepeatCount(Animation.INFINITE);
            this.startAnimation(rotation);
            queuePhoto(url, activity, this);
        }
    }

    @Override
    public void onl oadSuccess(String url, Bitmap bmp) {
        if (url.equals(myUrl)) {
            setimageBitmap(bmp);
        } else {
            /* the arrived bitmap is stale. do nothing. */
        }
    }

    @Override
    public void onl oadFail(String url) {
        if (url.equals(myUrl)) {
            setimageBitmap(((BitmapDrawable)getResources().getDrawable(stub_id)).getBitmap());
        } else {
            /* the Failed bitmap is stale. do nothing. */
        }
    }
    String myUrl;

    private void queuePhoto(final String url, final RemoteLoadListener listener)
    {
        new AsyncTask<Void, Void, Bitmap>() {
            @Override
            protected Bitmap doInBackground(Void... params) {
                //from web
                Bitmap bitmap = null;
                InputStream is = null;
                OutputStream os = null;
                try {
                    is = new URL(url).openStream();
                    os = new FileOutputStream(f);
                    Utils.copyStream(is, os);
                    bitmap = decodeFile(f);
                } catch (Exception ex){
                    bitmap = null;
                } finally {
                    if (is != null) try { is.close(); } catch (IOException e) { /* ignore */ };
                    if (os != null) try { os.close(); } catch (IOException e) { /* ignore */ };
                }
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap result) {
                if (result != null) {
                    listener.onLoadSuccess(url, result);
                } else {
                    listener.onLoadFail(url);
                }
            };
        }.execute();
    }
}

PS:请注意尝试-在使用流时最终阻塞.

Android AdapterViewAnimator

Android AdapterViewAnimator

public abstract class AdapterViewAnimator extends AdapterView<T extends  Adapter> 

 java.lang.Object
  ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.AdapterView<Textends android.widget.Adapter>
        ↳android.widget.AdapterViewAnimator

已知直接子类

AdapterViewFlipper, StackView

一:类概述:

 AdapterViewAnimator继承自基类AdapterView,当在视图间切换时会显示动画.

二:xml属性:

android:animateFirstView

定义 ViewAnimation 首次显示时是否对当前视图应用动画.

一定是布尔值,“true”或“false”.

也可以是对包含该类型值的资源(形式为 “@[package:]type:name”)或主题属性(形式为 “?[package:][type:]name”)             的参照.

该属性与全局属性资源符号 animateFirstView 对应.

相关方法

android:inAnimation 

//标识显示视图时使用的动画.
//一定是对其它资源的参照,形式为“@[+][package:]type:name” 或“?[package:][type:]name”形式的主题属性.
//该属性与全局属性资源符号 inAnimation 对应.
//相关方法

android:loopViews 

//定义当动画执行到列表尾部后,是否循环执行到第一个视图.
//一定是布尔值,“true”或“false”.
//也可以是对包含该类型值的资源(形式为 “@[package:]type:name”)或主题属性(形式为 “?[package:][type:]name”) 的参照.
//该属性与全局属性资源符号 loopViews 对应.
//相关方法

android:outAnimation 

//标识隐藏视图时使用的动画.
//一定是对其它资源的参照,形式为“@[+][package:]type:name” 或“?[package:][type:]name”形式的主题属性.
//该属性与全局属性资源符号 outAnimation 对应.
//相关方法

三:公开的构造函数:

public AdapterViewAnimator ( Context context);  //引入自: API 级别11  

public AdapterViewAnimator ( Context context, AttributeSet attrs); // 引入自: API 级别11  

public AdapterViewAnimator ( Context context, AttributeSet attrs, int defStyleAttr);

四:公共方法:

public void advance ();// 引入自: API 级别11  

//由 AppWidgetHost 调用.在应用小部件中用于移动到下一个视图.

public void deferNotifyDataSetChanged (); // 引入自: API 级别14  

//该设置推迟向没有连接的、未确定 RemoteViewsAdapter 发送 notifyDataSetChanged 消息.

public void fyiWillBeAdvancedByHostKThx ();//  引入自: API 级别11  

//由 AppWidgetHost 调用.指出将来的某个时点,会调用 advance() 将AdapterViewAnimator 中的视图向前移动.这样子类可以执行一些必要的设置,比如停止自动移动他们的子视图.

 

public Adapter getAdapter () 引入自: API 级别11

返回当前与该小部件关联的适配器.

返回
用于提供视图内容的适配器.


public int getBaseline () 引入自: API 级别11

返回小部件顶端到文本基线的偏移量.如果小部件不支持基线对齐,该方法返回 -1.

返回
小部件顶端到文本基线的偏移量;或者是 -1 当小部件不支持基线对齐时.


public View getCurrentView () 引入自: API 级别11

返回当前显示的子视图.

返回
当前显示的视图.
参见
getDisplayedChild()


public int getDisplayedChild () 引入自: API 级别11

返回当前显示的子视图索引.


public ObjectAnimator getInAnimation () 引入自: API 级别11

返回视图进入屏幕时显示的动画.

返回
动画,当未设置时为空.
参见
setInAnimation(android.animation.ObjectAnimator)
setInAnimation(android.content.Context, int)


public ObjectAnimator getOutAnimation () 引入自: API 级别11

返回视图退出屏幕时显示的动画.

返回
动画,当未设置时为空.
参见
setOutAnimation(android.animation.ObjectAnimator)
setOutAnimation(android.content.Context, int)


public View getSelectedView () 引入自: API 级别11
返回
当前选中条目对应的视图;无选中条目时返回空.


public boolean onRemoteAdapterConnected () 引入自: API 级别11

适配器建立到 RemoteViewsService 的连接时的回调函数.


public void onRemoteAdapterDisconnected () 引入自: API 级别11

适配器断开到 RemoteViewsService 的连接时的回调函数.


public void onRestoreInstanceState ( Parcelable state) 引入自: API 级别11

允许视图重新应用之前由 onSaveInstanceState() 保存的内部状态的回调函数. 该方法得 state 参数不可能为空.

参数
state 之前由 onSaveInstanceState() 返回的状态信息.


public Parcelable onSaveInstanceState () 引入自: API 级别11

允许视图保存其内部状态的回调函数,以便于之后使用相同状态创建新实例. 该状态应该只包含非持久的或者之后不可重现的信息.例如,你不能保存视图在屏幕上的位置,因为在创建新视图时,会在视图得层次结构中重新计算它的位置.

这里是一些可以保存的信息的例子:文本框中当前光标的位置(通常不是文字内容本身,因为文字内容一般保存在内容提供者或其他持久的储存器中),列表视图中的当前选中条目等等.

返回
返回包含视图当前状态的 Parcelable 对象,当不想保存状态时返回空.默认实现返回空.


public boolean onTouchEvent ( MotionEvent ev) 引入自: API 级别11

实现该方法可以处理触屏动作事件.

参数
ev 动作时间
返回
如果处理了事件,返回真;否则返回假.


public void setAdapter ( Adapter adapter) 引入自: API 级别11

设置用于为该小部件的视图提供用于显示的数据的适配器.

参数
adapter 用于创建视图内容的适配器.


public void setAnimateFirstView (boolean animate) 引入自: API 级别11

设置视图动画对象首次显示时,是否为当前视图显示动画.

参数
animate 视图动画对象首次显示时为当前视图显示动画时为真;否则为假.


public void setDisplayedChild (int whichChild) 引入自: API 级别11

设置显示那个子视图.

参数
whichChild 要显示的子视图索引


public void setInAnimation ( ObjectAnimator inAnimation) 引入自: API 级别11

指定视图进入屏幕时显示的动画.

参数
inAnimation 视图进入屏幕时启动的动画
参见
getInAnimation()
setInAnimation(android.content.Context, int)


public void setInAnimation ( Context context, int resourceID) 引入自: API 级别11

指定视图进入屏幕时显示的动画.

参数
context 应用程序上下文
resourceID 动画的资源 ID
参见
getInAnimation()
setInAnimation(android.animation.ObjectAnimator)


public void setOutAnimation ( Context context, int resourceID) 引入自: API 级别11

指定视图退出屏幕时显示的动画.

参数
context 应用程序上下文
resourceID 动画的资源 ID
参见
getOutAnimation()
setOutAnimation(android.animation.ObjectAnimator)


public void setOutAnimation ( ObjectAnimator outAnimation) 引入自: API 级别11

指定视图退出屏幕时显示的动画.

参数
outAnimation 视图退出屏幕时启动的动画
参见
getOutAnimation()
setOutAnimation(android.content.Context, int)


public void setRemoteViewsAdapter ( Intent intent) 引入自: API 级别11

将 AdapterViewAnimator 设置为使用通过制定的意图连接的 RemoteViewsService 的远程视图适配器.

参数
intent 用于标识适配器连接的 RemoteViewsService 的意图.


public void setSelection (int position) 引入自: API 级别11

设置当前选择条目.为了支持无障碍功能,重写该方法的子类必须首先调用父类的该方法.

参数
position 选择的数据条目的索引(从零开始).


public void showNext () 引入自: API 级别11

显示下一个子视图.


public void showPrevious () 引入自: API 级别11

显示上一个子视图.

 

保护的方法

protected void onLayout (boolean changed, int left, int top, int right, int bottom) 引入自: API 级别11

该视图设置其子视图的大小及位置时调用.派生类可以重写此方法,并为其子类布局.

参数
changed 是否为视图设置了新的大小和位置.
left 相对于父视图的左侧的位置.
top 相对于父视图的顶部的位置.
right 相对于父视图的右侧的位置.
bottom 相对于父视图的底部的位置.


protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) 引入自: API 级别11

评估视图及其内容,以决定其宽度和高度.此方法由 measure(int, int) 调用,子类可以重载以提供更精确、更有效率的衡量其内容尺寸的方法.

约定: 覆盖该方法时,必须调用 setMeasuredDimension(int, int) 方法来保存评估结果的视图的宽度和高度.如果忘记将导致 measure(int, int) 方法抛出IllegalStateException异常.要有效的利用父类的 onMeasure(int, int)方法.

基类测量的是背景的大小,除非 MeasureSpec 允许超过背景.子类应该重写 onMeasure(int, int) 方法,以为其内容提供更适合的大小.

如果重写了该方法,子类要确保其高度和宽度大于等于视图的最小高度和宽度. ( getSuggestedMinimumHeight() 和 getSuggestedMinimumWidth())

参数
widthMeasureSpec 父视图要求的横向空间大小.该要求由 View.MeasureSpec 进行了编码处理.
heightMeasureSpec 父视图要求的纵向空间大小.该要求由 View.MeasureSpec 进行了编码处理.
取自“ http://wikidroid.sinaapp.com/Android.widget.AdapterViewAnimator”

 

 

 

 

 

 

 

 

 

 

 

 

 

Android AdapterViewAnimator控件

Android AdapterViewAnimator控件

AdapterViewAnimator(堆View),已知子类有AdapterViewFlipper, StackView,是一系列View的集合,这些View叠加一起,并且View之间可以进行切换,并且在多个View切换过程体现渐隐渐现的动画效果。通过AdapterViewAnimator.setAdapter()方法设置一组要显示的View,通过AdapterViewAnimator.showPrevious()方法移动到前一个View,通过AdapterViewAnimator.showNext()移动到下一个View

Android Animation 之 ViewAnimator\ViewFlipper

Android Animation 之 ViewAnimator\ViewFlipper

选自 Android 3.0 Animations Beginners Guide Bring Your Android Applications To Lefe With Stunning Animations

动画 http://stackoverflow.com/questions/5151591/android-left-to-right-slide-animation

Viewpper 是一个为了翻页动画而封装的小类。它使用 tween 动画类,并将它们扩展到 xml 文件。

main.xml

ViewFlipper 有两个属性,android:inAnimation 和 android.outAnimation,可以设置进出动画

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ViewFlipper
        android:id="@+id/pages"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/text_1_1" />

            <ImageView
                android:id="@+id/rollingball"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="60dp"
                android:src="@drawable/ball"
                android:contentDescription="@string/app_name" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/text_1_2" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/text_2_1" />

            <ImageView
                android:id="@+id/bouncingball"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="60dp"
                android:src="@drawable/ball"
                android:contentDescription="@string/app_name" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/text_2_2" />
        </LinearLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/text_3_1" />
    </ViewFlipper>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" >

        <Button
            android:id="@+id/prev"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawableLeft="@android:drawable/ic_media_previous"
            android:text="@string/button_prev" />

        <Button
            android:id="@+id/next"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawableRight="@android:drawable/ic_media_next"
            android:text="@string/button_next" />
    </LinearLayout>

</LinearLayout>

slidein_to_left.xml     //in from right to left   used by next button

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toXDelta="0" />

</set>

slideout_to_left.xml     //out from right to left used by next button

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="-100%p" />

</set>

slidein_to_right.xml     //in from left to right   used by previous button

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <translate
        android:duration="500"
        android:fromXDelta="-100%p"
        android:toXDelta="0" />

</set>

slideout_to_right.xml     //out from left to right   used by previous button

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="100%p" />

</set>

MainActivity.java

package com.animation.interactivebook;

import android.os.Bundle;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
//import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ViewAnimator;

public class InteractiveBook extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		final View rollingBall = findViewById(R.id.rollingball);
		ObjectAnimator ballRoller = ObjectAnimator.ofFloat(rollingBall,
				"TranslationX", 0, 400);
		ballRoller.setDuration(2000);
		ballRoller.setRepeatMode(ObjectAnimator.REVERSE);
		ballRoller.setRepeatCount(ObjectAnimator.INFINITE);
		ballRoller.start();

		final View bouncingBall = findViewById(R.id.bouncingball);
		ValueAnimator ballBouncer = ValueAnimator.ofInt(0, 40);
		ValueAnimator.setFrameDelay(50);
		ballBouncer
				.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
					public void onAnimationUpdate(ValueAnimator ballBouncer) {
						// We''ll fill this out in a minute
						final int animatedValue = (Integer) ballBouncer
								.getAnimatedValue();
						bouncingBall.post(new Runnable() {
							public void run() {
								bouncingBall.setPadding(
										bouncingBall.getPaddingLeft(),
										40 - animatedValue,
										bouncingBall.getPaddingRight(),
										animatedValue);
								bouncingBall.invalidate();
							}
						});
					}
				});
		ballBouncer.setDuration(2000);
		ballBouncer.setRepeatMode(ValueAnimator.REVERSE);
		ballBouncer.setRepeatCount(ValueAnimator.INFINITE);
		ballBouncer.start();

		final AnimationSet slideinToLeft = new AnimationSet(true);
		TranslateAnimation slide1 = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT, 1f, Animation.RELATIVE_TO_PARENT,
				0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
		ScaleAnimation scale1 = new ScaleAnimation(10, 1, 10, 1);
		slideinToLeft.addAnimation(slide1);
		slideinToLeft.addAnimation(scale1);
		slideinToLeft.setDuration(1000);

		final AnimationSet slideoutToLeft = new AnimationSet(true);
		TranslateAnimation slide2 = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT,
				-1f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
				0);
		ScaleAnimation scale2 = new ScaleAnimation(1, 10, 1, 10);
		slideoutToLeft.addAnimation(slide2);
		slideoutToLeft.addAnimation(scale2);
		slideoutToLeft.setDuration(1000);

		final AnimationSet slideinToRight = new AnimationSet(true);
		TranslateAnimation slide3 = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT, -1f,
				Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_SELF, 0,
				Animation.RELATIVE_TO_SELF, 0);
		ScaleAnimation scale3 = new ScaleAnimation(10, 1, 10, 1);
		slideinToRight.addAnimation(slide3);
		slideinToRight.addAnimation(scale3);
		slideinToRight.setDuration(1000);

		final AnimationSet slideoutToRight = new AnimationSet(true);
		TranslateAnimation slide4 = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT,
				1f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
				0);
		ScaleAnimation scale4 = new ScaleAnimation(1, 10, 1, 10);
		slideoutToRight.addAnimation(slide4);
		slideoutToRight.addAnimation(scale4);
		slideoutToRight.setDuration(1000);

		final ViewAnimator pages = (ViewAnimator) findViewById(R.id.pages);
		Button prev = (Button) findViewById(R.id.prev);
		Button next = (Button) findViewById(R.id.next);
		prev.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// pages.clearAnimation();
				// Animation inAnimation =
				// AnimationUtils.loadAnimation(InteractiveBook.this,
				// R.anim.slidein_to_right);
				// Animation outAnimation =
				// AnimationUtils.loadAnimation(InteractiveBook.this,
				// R.anim.slideout_to_right);
				// pages.setInAnimation(inAnimation);
				// pages.setOutAnimation(outAnimation);
				pages.clearAnimation();
				pages.setInAnimation(slideinToRight);
				pages.setOutAnimation(slideoutToRight);
				pages.showPrevious();
			}
		});
		next.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// pages.clearAnimation();
				// Animation inAnimation =
				// AnimationUtils.loadAnimation(InteractiveBook.this,
				// R.anim.slidein_to_left);
				// Animation outAnimation =
				// AnimationUtils.loadAnimation(InteractiveBook.this,
				// R.anim.slideout_to_left);
				// pages.setInAnimation(inAnimation);
				// pages.setOutAnimation(outAnimation);
				pages.clearAnimation();
				pages.setInAnimation(slideinToLeft);
				pages.setOutAnimation(slideoutToLeft);
				pages.showNext();
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.interactive_book, menu);
		return true;
	}

}


Android ImageView setImageBitmap 不显示图片

Android ImageView setImageBitmap 不显示图片

从sd卡里读出图片后有时调用setImageBitmap(bitmap)方法会显示不出图片,仔细考虑过后原来是加载的图片过大导致的,解决办法为:

BitmapFactory.Options op = new BitmapFactory.Options();

op.inSampleSize = 2;

//op.inJustDecodeBounds = true; //它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。            

//op.inPreferredConfig = Bitmap.Config.ARGB_4444;    // 默认是Bitmap.Config.ARGB_8888



private Bitmap createBitmapFromByteData(byte[] data ,Options options){
        
        Bitmap bitmap = null;
        if(options == null){
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        }else{
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
        }
        return bitmap;
}

这样返回的bitmap就可以被显示出来了。

今天关于android-ListAdapter任务不可能吗?将ImageViews和Animations结合在一起吗?android listview baseadapter的分享就到这里,希望大家有所收获,若想了解更多关于Android AdapterViewAnimator、Android AdapterViewAnimator控件、Android Animation 之 ViewAnimator\ViewFlipper、Android ImageView setImageBitmap 不显示图片等相关知识,可以在本站进行查询。

本文标签: