Search code examples
androidandroid-scrollview

How to change size of ImageView in addOnScrollChangedListener dynamically?


I have a problem with changing the size of images trough addOnScrollChangedListener. I have them with setScaleType(ImageView.ScaleType.FIT_XY) . My code:

final int[] last_scrollX = {width};

    hv.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            //int scrollY = hv.getScrollY(); // For ScrollView
            int scrollX = hv.getScrollX(); // For HorizontalScrollView

            if(scrollX>last_scrollX[0]) {
                    IV_4.getLayoutParams().width = (int) (IV_4.getLayoutParams().width / 1.01);
                    IV_4.getLayoutParams().height = IV_4.getLayoutParams().width*2;
                    IV_2.getLayoutParams().width = (int) (IV_2.getLayoutParams().width * 1.01);
                    IV_2.getLayoutParams().height = IV_2.getLayoutParams().width*2;
                } else if (scrollX<last_scrollX[0]) {
                    IV_4.getLayoutParams().width = (int) (IV_4.getLayoutParams().width * 1.01);
                    IV_4.getLayoutParams().height = IV_4.getLayoutParams().width*2;
                    IV_2.getLayoutParams().width = (int) (IV_2.getLayoutParams().width / 1.01);
                    IV_2.getLayoutParams().height = IV_2.getLayoutParams().width*2;
                }
                last_scrollX[0]=scrollX;
        }
    });
}

I want to decrease and increase their size when the HorizontallScrollView hv is scrolling back and forth, but when I scroll they wont change their size. WHEN i minimize the app and then maximize it again or focus edit text in the activity the images change their size (very large or very small). EDIT: Forgot to mention that these images are in a ConstraintLayout behind the scrollview. So they are not in the scrollview hence not in a linearlayout. This is what i get now: https://image.ibb.co/naJiqT/ezgif_5_e9c1de6230.gif IV_4 is the left image and IV_2 is the right image and I want them to change size on scroll but right now they change only when I minimize/maximize the app or when I focus the edittext. EDIT2: I can see how I can do the thing I'v done so far with page transformer, I've never used it but as far as I can see it will be very hard to make the images scale + and - and changing their position at the same time while transforming. I need to understand why their size wont change while scrolling, but when I minimize/maximize the app or focus the edittext the onscrollchange code shows it's changes on the images.


Solution

  • You can use a ViewPager to get the same effect with custom page transformer attached to the ViewPager

    public class CustPagerTransformer implements ViewPager.PageTransformer {
    
    private int maxTranslateOffsetX;
    private ViewPager viewPager;
    
    public CustPagerTransformer(Context context) {
        this.maxTranslateOffsetX = dp2px(context, 180);
    }
    
    public void transformPage(View view, float position) {
        if (viewPager == null) {
            viewPager = (ViewPager) view.getParent();
        }
    
        int leftInScreen = view.getLeft() - viewPager.getScrollX();
        int centerXInViewPager = leftInScreen + view.getMeasuredWidth() / 2;
        int offsetX = centerXInViewPager - viewPager.getMeasuredWidth() / 2;
        float offsetRate = (float) offsetX * 0.38f / viewPager.getMeasuredWidth();
        float scaleFactor = 1 - Math.abs(offsetRate);
        if (scaleFactor > 0) {
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);
            view.setTranslationX(-maxTranslateOffsetX * offsetRate);
        }
    }
    
    /**
     * dp和像素转换
     */
    private int dp2px(Context context, float dipValue) {
        float m = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * m + 0.5f);
    }}
    

    attach this to viewpager as below

            viewPager.setPageTransformer(false, new CustPagerTransformer(HomeActivity.this));