为什么项目在Android GridView中滚动时会更改顺序? [英] Why items change order upon scrolling in Android GridView?

查看:74
本文介绍了为什么项目在Android GridView中滚动时会更改顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在android中有一个GridView,我用从xml资源检索的数据填充它.
例如,我在GridView中有15个项目按顺序放置.整体高度超过了屏幕高度,所以我必须滚动才能看到其余的项目.
问题是当我向上滚动时,不可见行的顺序已更改.这是一种神秘的行为,因为有时项目会彼此交换行. 这是我的getView方法:

I have a GridView in android which I fill it with data retrieved from a xml resource.
For example I have 15 items in the GridView which are placed in order. The overall height exceeds the Screen height so i have to scroll to see the rest of the items.
The problem is when I scroll back up, the order of the invisible rows have changed. It's a mysterious behavior as sometimes items swap rows with each other. Here is my getView method:

public class ImageAdapter extends BaseAdapter {
        public ImageAdapter(Context c, NodeList cuu) {
                cu = cuu;
        }
        public int getCount() {
                Log.d("Node Count",cu.getLength()+"");
                return cu.getLength();
        }
        public Object getItem(int position) {
                return position;
        }
        public long getItemId(int position) {
                return position;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
                View myView = convertView;
                if (convertView == null) {
                    Node nd = cu.item(position);
                    Log.d("nodes","Pos: "+(position)+" Name: "+nd.getNodeName()+" Title: "+nd.getAttributes().getNamedItem("title").getTextContent());
                    int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id").getTextContent());
                    LayoutInflater li = getLayoutInflater();
                    myView = li.inflate(R.layout.grid_item, null);
                   ImageView imageView = (ImageView) myView.findViewById(R.id.grid_item_image);
                   myView.setLayoutParams(new GridView.LayoutParams(70, 100));
                   id.download(nd.getAttributes().getNamedItem("icon").getTextContent(),imageView);
                   TextView textView = (TextView) myView.findViewById(R.id.grid_item_text);
                   textView.setText(nd.getAttributes().getNamedItem("title").getTextContent());
                   myView.setTag((Object) catID);
                }else{
                    //Log.d("nodes","Pos: "+(position));
                }
                return myView;
        }
        private NodeList cu = null;
    }

更新:嗯,这很奇怪.经过更多调试之后,我注意到在GridView中,适配器跳过了第13个位置,这意味着它返回1而不是13,然后继续前进到14! (我猜这13个运气不好!)

Update: Well, it's rather odd. After some more debugging I noticed that in the GridView, the Adapter skips the 13th position, meaning it returns 1 instead of 13 and then moves on to 14!!! (I guess the 13 is bad luck!)

推荐答案

如果这是您在getView方法中拥有的所有代码,则说明您执行的不是正确的方法:

If that is all the code you have in the getView method you're not implementing it right:

public View getView(int position, View convertView, ViewGroup parent) {
        View myView = convertView;
        if (myView == null) {           
            Node nd = cu.item(position);
            int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id")
                    .getTextContent());
            LayoutInflater li = getLayoutInflater();
            myView = li.inflate(R.layout.grid_item, null);
            myView.setLayoutParams(new GridView.LayoutParams(70, 100));         
            myView.setTag((Object) catID);
        } 
        Node nd = cu.item(position);
        Log.d("nodes", "Pos: " + (position) + " Name: " + nd.getNodeName()
                + " Title: "
                + nd.getAttributes().getNamedItem("title").getTextContent());
        ImageView imageView = (ImageView) myView
                .findViewById(R.id.grid_item_image);
        id.download(nd.getAttributes().getNamedItem("icon")
                .getTextContent(), imageView);
        TextView textView = (TextView) myView
                .findViewById(R.id.grid_item_text);
        textView.setText(nd.getAttributes().getNamedItem("title")
                .getTextContent());
        return myView;
    }

我不知道上面的代码是否有效,您的代码有点奇怪.无论如何,我认为您看到的行为是正常的,因为您在适配器中所做的所有操作都是填充第一个可见元素,然后由于上下滚动,适配器将在 exact 元素之间重复使用相同的元素回收.在getView中,您应该:

I don't know if the code above works, yours is a bit strange. Anyway, I think the behavior you see its normal because all you do in your adapter is populating the first visible elements and then the adapter will be reusing the exact same elements when you scroll up and down because of the recycling. In the getView you should:

  • 检查convertView是否为null:
    • 如果是null,是时候为该GridView的元素充气一个新的View了.您还可以使用Holder模式来缓存查找组成的Views(而不是每次都使用findViewById进行搜索)(您可以将setTag元素用于膨胀的View,但这是Node数据中的一部分数据元素?!?您打算如何处理?!?)
    • 如果不是null,您将什么都不做(或者,如果您实现了holder模式,您将获得带有已搜索到的Views的标签)
    • Check if the convertView is null:
      • If it is null it's time to inflate a new View for this GridView's element. You could also use the holder pattern to cache looking for the composing Views(instead of searching with findViewById everytime)(You use the setTag element for the inflated View but it's a piece of data from the Node data element ?!? What do you plan to do with it?!?)
      • If it isn't null you'll do nothing(or if you implement the holder pattern you would get the tag with the already searched Views)

      这是您在if/else语句中应该做的

      And this is what you should do in that if/else statement

      • 在上面的部分之后,您将用数据填充Views(因此它们保存该位置的适当数据).
      • After the part above you'll populate the Views with data(so they hold the apropriate data for that position).

      这篇关于为什么项目在Android GridView中滚动时会更改顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆