Android 根据图片高度动态设置ViewPager高度

 

有图片的地方,就有需求。 
为什么一个App有那么多的Banner,这里就不吐槽了。我们还是直接进主题,如何让ViewPager自适应图片的高度。 
效果如下: 
这里写图片描述 
如何去改变ViewPager的高度,都知道用setLayoutParams,我们不清楚的是,在什么时候给Viewpager设置。聪明的孩子马上就想到,我们用ViewPager的时候,有一个OnPageChangeListener是用来监听viewpager滑动翻页的。

@Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

在这三个方法中,只有onPageScrolled是滑动过程一直调用的,而且刚好有个positionOffset是代表Viewpager的偏移量。这里我们不用OnPageSelected,光看Log日志,我们就知道它只有在页面position位置改变才会被调用,不满足Viewpager高度慢慢变化这个动态过程。 
那么在onPageScrolled里我们要如何操作呢。为了更通俗的解决这个初中数学问题,我决定拿出我封印多年的截图涂鸦技术,look 
这里写图片描述
从图片1到图片2,我们可以看成是图片1高度慢慢变大的过程,高度增量y =(img1高度-img2高度)的绝对值。看到这里,相信很多小伙伴就知道怎么算了,举个例子,如果你已经滑动了20%页面,那你滑动距离就是0.2x0.2x/高度增量h=x/y ,算出来的h就是图片1增长的高度了,而我们是要给ViewPager setLayoutParams,需要拿到的具体高度就是 图片1高度+h了。 
具体代码如下:

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.ImageViewTarget;
import com.bumptech.glide.request.target.SimpleTarget;

public class MainActivity extends AppCompatActivity {

    private ViewPager mViewpager;
    private String[] urls = {
            "http://f.hiphotos.baidu.com/zhidao/pic/item/3b87e950352ac65cbdbeff61fcf2b21193138a6d.jpg"
            , "http://c.hiphotos.baidu.com/zhidao/pic/item/562c11dfa9ec8a1359aa88b6f103918fa0ecc030.jpg",
            "http://c.hiphotos.baidu.com/zhidao/pic/item/faf2b2119313b07e6077d3bc0ad7912396dd8cb8.jpg"
    };
    private int[] imgheights;
    private int screenWidth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        screenWidth=ScreenUtil.getScreenWidth(this);
        initView();


    }
    public void initView() {
        mViewpager = (ViewPager) findViewById(R.id.viewpager);
//        mViewpager.setOffscreenPageLimit(3);
        Glide.with(this).load(urls[0]).asBitmap().into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                float scale = (float) resource.getHeight() / resource.getWidth();
                int defaultheight = (int) (scale * screenWidth);
                initViewPager(defaultheight);
            }
        });

    }
   //获取第一张图片高度后,给viewpager设置adapter
    private void initViewPager(final int defaultheight) {
        mViewpager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                if (imgheights == null || imgheights.length != urls.length){
                    imgheights = null;
                    imgheights = new int[urls.length];}
                return urls.length;
            }


            @Override
            public Object instantiateItem(ViewGroup container, final int position) {
                final ImageView imageView = new ImageView(MainActivity.this);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

                Glide.with(getApplicationContext()).load(urls[position]).asBitmap().into(new ImageViewTarget<Bitmap>(imageView) {
                    @Override
                    protected void setResource(Bitmap loadedImage) {
                        if(loadedImage!=null) {
                            float scale = (float) loadedImage.getHeight() / loadedImage.getWidth();
                            imgheights[position] = (int) (scale * screenWidth);
                            imageView.setImageBitmap(loadedImage);
                        }else {
                            Toast.makeText(MainActivity.this, "图片为空", Toast.LENGTH_LONG).show();
                        }
                    }
                });
                container.addView(imageView);
                return imageView;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView((View) object);
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }
        });


        mViewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (position == imgheights.length - 1) {
                    return;
                }

                //计算ViewPager现在应该的高度,heights[]表示页面高度的数组。
                int height = (int) ((imgheights[position] == 0 ? defaultheight : imgheights[position])
                        * (1 - positionOffset) +
                        (imgheights[position + 1] == 0 ? defaultheight : imgheights[position + 1])
                                * positionOffset);

                //为ViewPager设置高度
                ViewGroup.LayoutParams params = mViewpager.getLayoutParams();
                params.height = height;
                mViewpager.setLayoutParams(params);
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

}

还有一个需要注意的地方就是,我们平时加载网络图片的时候,是需要时间加载的,我们必须加载出viewpager的高度(第一张图片的高度)之后,才能去给viewpager设置adapter。我觉得比较好的方案是,在上个页面获取这个默认高度,或者让服务器返回第一张图片的宽高,我们就可以算出viewpager的默认高度了。而我在demo中是先网络请求出第一张图片的bitmap算出将要显示的高度defaultheight,才去setAdapter: 
这里写图片描述

原文地址:https://blog.csdn.net/qq_31390699/article/details/53738075

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值