GridView scrolling problem on Android

后端 未结 5 1575
走了就别回头了
走了就别回头了 2021-02-02 03:06

this must be somethng very simple I\'m overlooking, but I have the following problem (the post is rather lengthy, but I want to provide as much info as possible :) ).

I

相关标签:
5条回答
  • 2021-02-02 03:28

    The answer is view recycling.

    In general your getView should always be something of the form:

    public class ImageAdapter extends BaseAdapter {
    
        private List<String> mUrls; // put your urls here
        private Map<String, Drawable> mImages; // cache your images here
    
        public ImageAdapter() {
            ...
            mUrls = new ArrayList<String>();
            mImages = new HashMap<String, Drawable>();
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder; // Use the ViewHolder pattern for efficiency
    
            if (convertView == null) {
                // first time this view has been created so inflate our layout
                convertView = View.inflate(this, R.layout.my_grid_item, null);
                holder = new ViewHolder();
                holder.image = convertView.findViewById(R.id.image);
                holder.text = convertView.findViewById(R.id.text);
                convertView.setTag(holder); // set the View holder
            } else {
               holder = (ViewHolder) convertView.getTag();
            }
    
            // update the current view - this must be done EVERY
            // time getView is called due to view recycling
            holder.text.setText(Integer.toString(position));
    
            // check our cache for the downloaded image
            final String url = mUrls.get(position);
            if (mImages.get(url) != null)
                holder.image.setImageDrawable(mImages.get(url));
            else
                loadImage(url, holder.image);
    
            // return our view
            return convertView;
        }
    
        public loadImage(final String url, final ImageView image) {
            // load an image (maybe do this using an AsyncTask
            // if you're loading from network
        }
    
        ...
    }
    

    Where your ViewHolder class would look something like

    public class ViewHolder {
        ImageView thumbImage;
        TextView text;
    }
    

    Then you shouldn't run into any problems. Also I'm not sure why you needed to sleep in your getView? That will slow down scrolling of your GridView.

    0 讨论(0)
  • 2021-02-02 03:29

    guys to avoid this problem always return newly created object in getView()

    public View getView(int position, View convertView, ViewGroup parent) {
                    ImageView       imageView;
                    TextView        textView;
                    LinearLayout    linearlayout  = new LinearLayout(mContext);
                    //if (convertView == null) {
                        imageView       = new ImageView(mContext);
                        textView        = new TextView(mContext);
    
                        //imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
                        imageView.setAdjustViewBounds(false);
                        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                        imageView.setPadding(4, 8, 8, 8);                   
                        imageView.setBackgroundResource(mThumbIds[position]);
    
                        textView.setText(mThumbText[position]);                
                        textView.setGravity(0x01);
                        textView.setMaxLines(2);
    
                        //textView.setPadding(20, 0, 0, 0);
                        linearlayout.addView(imageView,0);
                        linearlayout.addView(textView,1);
                        linearlayout.setPadding(4, 4, 4, 4);
                        linearlayout.setOrientation(LinearLayout.VERTICAL);
                        linearlayout.setGravity(0x01);
    
                   // } else {
                        //linearlayout = (LinearLayout) convertView;
                    //}
    
                    return linearlayout;
                }
    
    0 讨论(0)
  • 2021-02-02 03:39

    I am experiencing the same problem. I'm moving in the direction of rendering views in the background;

    I'm studying these codes, if should help:

    http://blog.tomgibara.com/post/7665158012/android-adapter-view-rendering

    https://github.com/desertjim/LazyLoadingGridView

    0 讨论(0)
  • 2021-02-02 03:51

    Use the standard Lazy Loader to get the images but never update onpostexecute, which causes the images to update too fast and get the randomness you don't desire.

    I even used the code:

    if (result != null && !mFlinging && myPosition < 12)
    {   
       imageView.setImageBitmap(result);
    }
    

    int the onpostexecute which would then update the images correctly for the first screen, but if you fling the images screen then come back too quickly to the first screen get the randomness again so I now use the :

    mPhotoView.setOnScrollListener(new OnScrollListener() { 
    
    
    
                public void onScroll(AbsListView view, int firstVisibleItem,
                        int visibleItemCount, int totalItemCount) {
                    // TODO Auto-generated method stub
    
                }
    
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    // TODO Auto-generated method stub
                    if(scrollState != SCROLL_STATE_IDLE) {
                      mAdapter.setFlinging(true);
                    } else {
                      mAdapter.setFlinging(false);   
                    }
    
                    int first = view.getFirstVisiblePosition(); 
                    int count = view.getChildCount(); 
    
                    if (scrollState == SCROLL_STATE_IDLE || (first + count > mAdapter.getCount()) ) { 
                        mPhotoView.invalidateViews(); 
                    }
    
                } 
            }); 
    

    to update the view.

    0 讨论(0)
  • 2021-02-02 03:53

    Actually the problem here is that you set the content of the "convertView" within the if or else. Or you should always do that after instantiating the view if it is null and set the content only before returning the view.

    Consequently, you're sure the content of the view is always the right one, updated using the position and not a false recycled view.

    So your should generally speaking do the following:
    (based on the tutorial from Android Guide here)

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) { 
            imageView = new ImageView(mContext);
            //just creating the view if not already present
        } else {
            imageView = (ImageView) convertView;
            //re-using if already here
        }
    
        //here is the tricky part : set the content of the view out of the if, else
        //just before returning the view
        imageView.setImageResource(mThumbIds[position]);
        return imageView;
    }
    
    0 讨论(0)
提交回复
热议问题