简体   繁体   English

自定义ImageViews从ListAdapter中消失

[英]custom ImageViews disapearing from ListAdapter

Ok, my problem is similar to this Background image in ListView entries spontaneously disappearing 好吧,我的问题类似于ListView条目中的背景图像自发消失

but this issue is resolved with using setImageResource on a normal ImageView but I want an animation to exist on all elements of a list, and this can not be done without a custom ImageView class that allows the animation to run. 但是在普通的ImageView上使用setImageResource解决了这个问题,但是我希望动画存在于列表的所有元素上,如果没有允许动画运行的自定义ImageView类,就无法完成。 Does anyone know why these images are disappearing after scrolling in the list view and maybe how this can be fixed? 有没有人知道为什么这些图像在列表视图中滚动后消失了,也许这是如何解决的? Thanks a lot! 非常感谢!

Here is my ListAdapter: 这是我的ListAdapter:

    package com.mmgworldwide.layout.listadapters;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import com.mmgworldwide.R;
import com.mmgworldwide.customviews.SpinLoadingAnim;
import com.mmgworldwide.data.FWREvent;
import com.mmgworldwide.data.ImageThreadLoader;
import com.mmgworldwide.data.ImageThreadLoader.ImageLoadedListener;
import com.mmgworldwide.layout.ListDivider;
import com.mmgworldwide.data.Personality;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class PersonalityListAdapter extends ArrayAdapter<Object>{

    private Context parentContext;
    public ArrayList<Object> items_list_ref;
    private ImageThreadLoader imageLoader = new ImageThreadLoader();

    public PersonalityListAdapter(Context context, int resource, int textViewResourceId, ArrayList<Object> items_list) {
        super(context, resource, textViewResourceId, items_list);
        items_list_ref = items_list;
        parentContext = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Object node = (Object) items_list_ref.get(position);
        LayoutInflater inflater = (LayoutInflater) parentContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(node instanceof ListDivider){
            //make new div bar
            View div = inflater.inflate(R.layout.list_bar, parent, false);
            TextView div_label = (TextView) div.findViewById(R.id.div_label);
            div_label.setText(((ListDivider) node).label.toUpperCase());
            return div;
        }

        View row = inflater.inflate(R.layout.picture_list, parent, false);

        TextView name_txt = (TextView) row.findViewById(R.id.name_txt);
        TextView title_txt = (TextView) row.findViewById(R.id.title_txt);
        final ImageView portrait_img = (ImageView) row.findViewById(R.id.portrait);
        final ImageView load_cnt = (ImageView) row.findViewById(R.id.portrait_loadDisplay);

        name_txt.setText(((Personality) node).getName());
        SpannableString title_underlined = new SpannableString(((Personality) node).getTitle());
        title_underlined .setSpan(new UnderlineSpan(), 0, title_underlined.length(), 0);
        title_txt.setText(title_underlined);

        load_cnt.setVisibility(View.VISIBLE);

        return row;
    }

Here is my custom ImageView class 这是我的自定义ImageView类

package com.mmgworldwide.customviews;

import android.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

public class SpinLoadingAnim extends ImageView{

    AnimationDrawable animation;
    private final Integer FRAME_SPEED = 20;

    public SpinLoadingAnim(Context context, AttributeSet attrs){
        super(context, attrs);

         //setBackgroundColor(Color.GREEN);


        animation = new AnimationDrawable();
        animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00000), FRAME_SPEED);
        animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00001), FRAME_SPEED);
        animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00002), FRAME_SPEED);
        animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00003), FRAME_SPEED);

        animation.setOneShot(false);

        this.setBackgroundDrawable(animation);
        this.post(new Starter());
    }

    class Starter implements Runnable {
        public void run() {
            animation.start();

        }

    }

And here is my layout XML 这是我的布局XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="#FFFFFF"
  android:gravity="center_vertical"
  android:paddingTop="10dp"
  android:paddingBottom="10dp"
  android:paddingLeft="10dp"
  android:paddingRight="10dp">
    <ImageView android:layout_width="60dp" android:layout_height="60dp" android:id="@+id/portrait" android:layout_centerVertical="true"></ImageView>


    <com.mmgworldwide.customviews.SpinLoadingAnim
        android:id="@+id/portrait_loadDisplay" 
        android:layout_width="20dp" android:layout_height="20dp"
        android:background="#939598"
        android:layout_centerVertical="true" android:layout_marginLeft="20dp"
        android:layout_alignParentBottom="true" 
        android:layout_alignParentLeft="true" />



    <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerVertical="true" android:id="@+id/arrow" android:src="@drawable/list_arrow" android:layout_alignParentRight="true"></ImageView>
    <LinearLayout android:layout_toRightOf="@id/portrait" android:layout_toLeftOf="@id/arrow" android:layout_centerVertical="true" android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="wrap_content" android:baselineAligned="true" android:paddingLeft="15dp" android:paddingRight="15dp">
        <TextView android:text="CHEF NAME" android:id="@+id/name_txt" android:layout_width="wrap_content" android:textColor="#000000" android:textStyle="bold" 
            android:layout_height="wrap_content" android:paddingBottom="2dp" android:textSize="15sp"></TextView>
        <TextView android:text="Chef Title" android:id="@+id/title_txt" android:layout_width="wrap_content" android:textColor="#000000" 
            android:layout_height="wrap_content" android:textSize="13sp"></TextView>
    </LinearLayout>


</RelativeLayout>

Every 5th 'preloader' graphic is still disappearing, but thanks Michele this has helped a lot, and made things cleaner. 每隔5个“预加载器”图形仍在消失,但感谢Michele,这已经帮助了很多,并使事情变得更加清洁。

package com.mmgworldwide.layout;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.mmgworldwide.R;
import com.mmgworldwide.data.DataConnection;
import com.mmgworldwide.data.ImageThreadLoader;
import com.mmgworldwide.data.Personality;

//http://code.google.com/p/and-conference/source/browse/trunk/src/com/totsp/conference/PresentationList.java

public class Personalities extends Activity{

    private ListView listView;
    private ArrayAdapter<Object> adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.personalities);

        listView = (ListView) findViewById(R.id.personalitylistview);
        listView.setDrawingCacheEnabled(false);


        addListAdapter();

        setFooterView("more");
    }

    private void addListAdapter(){
        ArrayList<Object> adaptList = makeAdaptList();

        adapter = new PersonalityListAdapter(this, 0, adaptList);
        listView.setAdapter(adapter);
    }

    private ArrayList<Object> makeAdaptList(){
        ArrayList<Object> adaptList = new ArrayList<Object>();
        String currentDivDate = " ";
        for(Personality aEvent : DataConnection.fwrInfo.getPersonalityList()){
            adaptList.add(aEvent);
        }

        return adaptList;
    }

    private void setFooterView(String highlight){
        Footer footer = (Footer) findViewById(R.id.footer);
        footer.setHighlight(highlight);
    }

    //***********************************************************************************************************************************************
    //ViewHolder
    //***********************************************************************************************************************************************
    static class ViewHolder {
        private TextView tView1;
        private TextView tView2;
        private ImageView iView1;
    }

    //***********************************************************************************************************************************************
    //PersonalityListAdapter
    //***********************************************************************************************************************************************
    private class PersonalityListAdapter extends ArrayAdapter<Object>{

        LayoutInflater vi = (LayoutInflater) Personalities.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        private Context parentContext;
        public ArrayList<Object> items_list_ref;
        private ImageThreadLoader imageLoader = new ImageThreadLoader();

        public PersonalityListAdapter(final Context context, final int resId, final ArrayList<Object> presentations) {
            super(context, resId, presentations);
            this.items_list_ref = presentations;
            parentContext = context;
        }

        @Override
    public int getCount() {
        return items_list_ref.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //Log.d("TROY", "adding view");
            View v = convertView;

            if (v == null) {
                //Log.d("TROY", "inflation");
                v = vi.inflate(R.layout.picture_list, parent, false);
                ViewHolder viewHolder = new ViewHolder();

                viewHolder.tView1 = (TextView) v.findViewById(R.id.name_txt);
                viewHolder.tView2 = (TextView) v.findViewById(R.id.title_txt);
                viewHolder.iView1 = (ImageView) v.findViewById(R.id.portrait);

                v.setTag(viewHolder);
            }

            Object p = items_list_ref.get(position);

            if (p != null) {
                //Log.d("TROY", "setting stuff");
                ViewHolder viewHolder = (ViewHolder) v.getTag();
                viewHolder.tView1.setText("hi");
            }

            return v;
        }
    }

}

Here is a screen shot of what's going on (why is the 5th preload graphic not showing?): 这是一个正在发生的事情的屏幕截图(为什么没有显示第5个预加载图形?):

在此输入图像描述

edit ------ 编辑------

Ok, I added the getCount and getItemId overrides but still have the same issues, I figured I would start a project from scratch and try again with just a listView, same issue, I have put up a test project to demonstrate this frustrating issue. 好吧,我添加了getCount和getItemId覆盖,但仍然有相同的问题,我想我会从头开始一个项目并再次尝试使用listView,同样的问题,我已经提出了一个测试项目来演示这个令人沮丧的问题。 In this test I did not even add any data to the adapters, and the animation only works for some of them, just like with my master project. 在这个测试中,我甚至没有向适配器添加任何数据,并且动画仅适用于其中一些,就像我的主项目一样。

Thank you so much for your patience and help this far Michele, you have been very awesome. 非常感谢你的耐心和帮助米歇尔,你一直非常棒。

http://faceonfire.com/temp/ListTester.zip http://faceonfire.com/temp/ListTester.zip

ListViews are highly optimized Datastructures. ListViews是高度优化的数据结构。 You should use ViewHolders to obey the rules of Lists and make the life of the system a bit easier. 您应该使用ViewHolders遵守列表规则并使系统的生命更容易一些。

When you Scroll a ListView the System caches the Items in Holders for performance. 当您滚动ListView时,系统会缓存持有者中的项目以获得性能。 Read How to load the Listview "smoothly" in android 阅读如何在android中“顺利”加载Listview

you can also try to set 你也可以尝试设置

yourListView.setDrawingCacheEnabled(false);

edit: ok than try to set your animation with xml 编辑:确定比尝试使用xml设置动画

http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

like: 喜欢:

<!-- Animation frames are wheel0.png -- wheel5.png files inside the
 res/drawable/ folder -->
 <animation-list android:id="selected" android:oneshot="false">
    <item android:drawable="@drawable/wheel0" android:duration="50" />
    <item android:drawable="@drawable/wheel1" android:duration="50" />
    <item android:drawable="@drawable/wheel2" android:duration="50" />
    <item android:drawable="@drawable/wheel3" android:duration="50" />
    <item android:drawable="@drawable/wheel4" android:duration="50" />
    <item android:drawable="@drawable/wheel5" android:duration="50" />
 </animation-list>

edit2: please try to implement getCount and getItemId, theres something wrong with the boundarys of your List, maybe android cant find out on with position the list is after scrolling. edit2:请尝试实现getCount和getItemId,你的List的boundarys有问题,也许android无法找到有关滚动后列表的位置。 Oh and can you please test it with random data, not the same item all the way (perhaps some weird hash (default getItemId Implementation?) that is always the same with the same item content). 哦,你可以用随机数据来测试它,而不是一直都是相同的项目(也许是一些奇怪的哈希(默认的getItemId实现?),它总是与相同的项目内容相同)。 for example like this: 例如像这样:

@Override
public int getCount() {
    return <yourdatastructure>.getSize();
}

@Override
public long getItemId(int position) {
    return position;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM