【问题标题】:Customized ListView scrolling - Only Imageviews自定义 ListView 滚动 - 仅 Imageview
【发布时间】:2012-08-31 00:36:51
【问题描述】:

我的应用中有一个 ListView,其中只有 ImageView。根据随机选择方法,每行显示 1、2 或 3 个图像。但是我现在面临的问题是,当我滚动时,图像的顺序会发生变化,而我希望它们始终保持不变。另外,即使我使用了高效的“int”迭代器来检索和显示该行中的下一个图像,图像也会重复。

我检查了其他处理类似问题的问题,但它们不处理 ImageViews。我是新手,所以任何帮助将不胜感激。

public class YPAdapter extends BaseAdapter{

public Context context; 
public ArrayList<ImageDetails> flowImages = new ArrayList<ImageDetails>();
LayoutInflater inflater;
private ArrayList mData = new ArrayList();
public int i = Home.getStart();

YPAdapter(Context context, ArrayList<ImageDetails> name, int start) {
    inflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);     
    this.context = context; 
    this.flowImages = name; 
}
public void addItem(final int item) {
    mData.add(item);
    notifyDataSetChanged();
    }   
@Override
public int getViewTypeCount() {
    return 3;
}
@Override
    public int getCount() {
    return mData.size();
    }

@Override
public int getItemViewType(int position) {
int x = 0;
    if (Integer.parseInt(mData.get(position).toString()) == 1) x = 0;
    else if(Integer.parseInt(mData.get(position).toString()) == 2) x = 1;
    else if(Integer.parseInt(mData.get(position).toString()) == 3) x = 2;
    return x;
}

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


    int mode = getItemViewType(position);



        if(convertView == null)
        {   

        switch(mode){

        case 0:

            convertView = inflater.inflate(R.layout.image_container_1, parent, false);
        if(i < (flowImages.size()))
        {
        ImageView imageView = (ImageView) convertView.findViewById(R.id.logo_1);

        ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

        dimensions = ImageSorter.getLayout(1);

        // get parameters

                // set image with url

        i++;

        }       

        break;

        case 1:                  
                convertView = inflater.inflate(R.layout.image_container_2, parent, false);          

        if(i < (flowImages.size()-1))
        {
        ImageView imageView1 = (ImageView) convertView.findViewById(R.id.logo_2_1);
        ImageView imageView2 = (ImageView) convertView.findViewById(R.id.logo_2_2);

        ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

         // get parameters for 2 images

                // set image for first imageview    
        i++;
           // set image for second imageview
           i++;
        }
        break;

        case 2:              
                convertView = inflater.inflate(R.layout.image_container_3, parent, false);

        if(i < (flowImages.size()-2))
        {
        ImageView imageView1 = (ImageView) convertView.findViewById(R.id.logo_3_1);
        ImageView imageView2 = (ImageView) convertView.findViewById(R.id.logo_3_2);
        ImageView imageView3 = (ImageView) convertView.findViewById(R.id.logo_3_3);

        ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

       // get parameters for 3 images

                // set image with url for first imageview
        i++;
        // set image for second imageview
        i++;
    // set image for third imageview
               i++;
        }

        break;
    }   
    }


    return convertView;

}



public Object getItem(int position) {
     return mData.get(position);
}

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

}

这是 ListView 的 XML:

<ListView
android:id = "@+id/home_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"       
    >         
</ListView>      

【问题讨论】:

  • 你能在适配器和列表视图项xml中显示你的代码
  • 您需要发布您的代码(尤其是您的列表适配器)。否则,我们只是在猜测您是如何实现这一点的,除了模糊的潜在答案之外,我们无法提供任何其他答案。
  • 我已添加您要求的代码。希望现在很清楚。 :)
  • 我分配给 i 的 Home.getstart() 方法是我将检索的第一张图像的索引。

标签: java android android-listview android-imageview


【解决方案1】:

但我现在面临的问题是,当我滚动时,顺序 的图像被改变了,当我希望它们保持不变时 时间。

这很可能是因为您设置getViewItemType 方法的方式(或者您尝试在getView 中执行此操作,这是错误的)。我不明白你希望你的行类型如何显示,所以除非你更好地解释行应该如何显示,否则我不能向你推荐一些东西。

另外,即使我使用了 高效的“int”迭代器来检索和显示下一个图像 行。

发生这种情况是因为您没有编写getView() 方法来考虑ListView 的回收机制。您应该永远不要仅为convertView 为空的情况设置数据,因为这意味着当ListView 回收行时,您不会为回收行设置正确的数据.

例如:

     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
        int mode = getItemViewType(position);
        if(convertView == null) {   
            switch(mode){
            case 0:
                convertView = inflater.inflate(R.layout.image_container_1, parent, false);
            break;
            case 1:                  
                convertView = inflater.inflate(R.layout.image_container_2, parent, false);          
            break;
            case 2:              
                convertView = inflater.inflate(R.layout.image_container_3, parent, false);
            break;
            }   
        }
        switch (mode) {
        case 0:
                    if(i < (flowImages.size()))
            {
            ImageView imageView = (ImageView) convertView.findViewById(R.id.logo_1);

            ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

            dimensions = ImageSorter.getLayout(1);

            // get parameters

                    // set image with url

            i++; // I don't know what you try to measure with this variable but 
            // you shouldn't do it in a method like getView as this method is called a lot of times
            // for example the user coculd be playing, scrolling the ListView one item down and one item up for 500 times.
            } 
        break;        
        case 1:
            if(i < (flowImages.size()-1))
            {
            ImageView imageView1 = (ImageView) convertView.findViewById(R.id.logo_2_1);
            ImageView imageView2 = (ImageView) convertView.findViewById(R.id.logo_2_2);

            ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

             // get parameters for 2 images

                    // set image for first imageview    
            i++;
               // set image for second imageview
               i++;
            }

        break;       
        case 2:

            if(i < (flowImages.size()-2))
            {
            ImageView imageView1 = (ImageView) convertView.findViewById(R.id.logo_3_1);
            ImageView imageView2 = (ImageView) convertView.findViewById(R.id.logo_3_2);
            ImageView imageView3 = (ImageView) convertView.findViewById(R.id.logo_3_3);

            ArrayList<ImageDimensions> dimensions = new ArrayList<ImageDimensions>();

           // get parameters for 3 images

                    // set image with url for first imageview
            i++;
            // set image for second imageview
            i++;
        // set image for third imageview
                   i++;
            }


    break;
    }
    return convertView;

}

为什么不需要只考虑convertView == null 的情况:

ListView 需要显示新行时(列表第一次出现在屏幕上或用户向上或向下滚动时),它将调用getView 方法。当一行从屏幕上消失时,ListView 可以选择将该行保留在缓存中以供以后再次调用 getView 方法时使用(通过这样做,getView 方法将不必构建该行再次,避免创建不必要的对象)。因此,在getView 方法中,您应该始终检查convertView 是否为null。如果它为空,则构建行(并在空检查设置数据之后)。如果它不为空,那么您有一个回收视图,并且无需构建新行,您只需在其上设置数据(如果您在空检查中设置数据,那么回收视图将保留旧数据(从以前的位置),你会得到奇怪的结果)。

getItemViewType 将在 getView 方法之前调用,以让 ListView 检查它是否具有该类型的回收视图(因此无论您在什么位置,都可以保证获得正确的回收视图)。在这里,我仍然不明白您要如何设置图像。您有 flowImages 列表,其中可能包含您的图像,但我不知道您希望如何分配它们,顺序,随机等

【讨论】:

  • 嘿,回答您关于我希望我的行看起来如何的问题 - 每行根据模式显示一个、两个或三个图像。我有一个相应地返回图像尺寸的类。从不同的教程中,我看到在 getView() 方法中调用了 getItemViewType() 方法。我不确定如何使用它。你能建议一种不同的方式吗?还有关于不只是处理“convertView==null”的情况,我仍然不清楚。
  • 哦,一排显示的图片数量是随机的。在调用适配器之前,我在数组列表中设置了它。我将它传递给适配器并使用它来确定每行必须具有的图像数量。这就是我对 mData 变量所做的事情。
【解决方案2】:

删除此条件
if(convertView == null)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2011-10-16
    相关资源
    最近更新 更多