02ViewPager高度自适应轮播图

Posted 清风百草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02ViewPager高度自适应轮播图相关的知识,希望对你有一定的参考价值。

(1)高度自适应ViewPager
(2)解决ViewPager设置高度为wrap_content无效的方法

【02】ViewPager高度自适应轮播图

1.效果

在这里插入图片描述

2.源码

2.1自定义ViewPager

(1)核心子View测量

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;


/**
 * @author XiongJie
 * @version appVer
 * @Package com.gdc.knowledge.highui.hightviewpager
 * @file
 * @Description:
 * 1.高度自适应ViewPager
 * (1)解决ViewPager设置高度为wrap_content无效的方法
 *
 * @date 2021-6-7 23:35
 * @since appVer
 */

public class MyViewPager extends ViewPager {

    private static final String TAG = "MyViewPager";

    public MyViewPager(@NonNull Context context) {
        super(context);
    }

    public MyViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {


        int height = 0;
        Log.d(TAG, "onMeasure: getChildCount: " + getChildCount());

        /**
         * 1.测量子View的大小
         * (1)需要将子View的大小转换为具体的宽高
         */
        for(int i = 0 ; i < getChildCount(); i++){
            View child = getChildAt(i);

            //1.1先要获取子View的LayoutParams然后再测量
            ViewGroup.LayoutParams lp = child.getLayoutParams();

            int childWidthSpec = getChildMeasureSpec(widthMeasureSpec,0,lp.width);
            int childHightSpec = getChildMeasureSpec(heightMeasureSpec,0,lp.height);

            //1.2测量子View的大小
            child.measure(childWidthSpec,childHightSpec);

            //1.2获取测量之后的实际高度
            int h = child.getMeasuredHeight();
            if(h > height){
                height = h;
            }
            Log.d(TAG, "onMeasure: "  + h + " height: " + height);
        }

        //2.设置高度测量模式
        heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height,
                MeasureSpec.EXACTLY);

        //3.保存测量结果
        setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);

        //4.测量ViewPager自己
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

2.1Activity

public class ViewPagerHeightWrapActivity extends AppCompatActivity {

    private ViewPager     viewPager;
    private RadioGroup    radioGroup;
    private List<Integer> images;

    private int     index;
    private int     preIndex;
    private Timer   timer      = new Timer();
    private boolean isContinue = true;

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

        viewPager = findViewById(R.id.view_Pager);
        radioGroup = findViewById(R.id.radio_group);
        images = new ArrayList<>();

        images.add(R.drawable.p1);
        images.add(R.drawable.p2);
        images.add(R.drawable.p3);
        images.add(R.drawable.p4);
        images.add(R.drawable.p5);

        MyPagerAdapter pagerAdapter = new MyPagerAdapter(images,this);

        viewPager.setPageMargin(30);
        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(onPageChangeListener);
        viewPager.setPageTransformer(true, new PageTransform());

        //指示器
        initRadioButton(images.size());

        //轮播
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isContinue) {
                    handler.sendEmptyMessage(1);
                }
            }
        }, 2000, 2000);
    }

    /**
     * RadioButton
     * @param length
     */
    private void initRadioButton(int length) {
        for (int i = 0; i < length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(R.drawable.rg_selector);
            imageView.setPadding(20, 0, 0, 0);
            radioGroup.addView(imageView, ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            radioGroup.getChildAt(0).setEnabled(false);
        }
    }

    ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            index = position;
            setCurrentDot(index % images.size());
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };

    private void setCurrentDot(int i) {
        if (radioGroup.getChildAt(i) != null) {
            //当前按钮不可改变
            radioGroup.getChildAt(i).setEnabled(false);
        }
        if (radioGroup.getChildAt(preIndex) != null) {
            //上个按钮可以改变
            radioGroup.getChildAt(preIndex).setEnabled(true);
            //当前位置变为上一个,继续下次轮播
            preIndex = i;
        }
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 1:
                index++;
                viewPager.setCurrentItem(index);
            }
        }
    };
}

2.3PagerAdapter

public class MyPagerAdapter extends PagerAdapter {

    private static final String        TAG = "MyPagerAdapter";
    private List<Integer> mImages;
    private Context       mContext;

    MyPagerAdapter(List<Integer> images, Context context) {
        mImages = images;
        mContext = context;
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

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

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        position = position % mImages.size();
        View view = LayoutInflater
                .from(mContext).inflate(R.layout.linear_item, container, false);

        ImageView imageView = view.findViewById(R.id.iv_page);
        imageView.setImageResource(mImages.get(position));

        TextView textView = view.findViewById(R.id.tv);
        textView.setText(position + " ");
        container.addView(view);

        return view;
    }

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

2.4切换特效

public class PageTransform implements ViewPager.PageTransformer{

    private static final float DEFAULT_MIN_ALPHA = 0.3f;
    private float mMinAlpha = DEFAULT_MIN_ALPHA;

    private static final float DEFAULT_MAX_ROTATE = 15.0f;
    private float mMaxRotate = DEFAULT_MAX_ROTATE;

    @Override
    public void transformPage(@NonNull View page, float position) {
        if (position < -1) {
            //透明度
            page.setAlpha(mMinAlpha);
            //旋转
            page.setRotation(mMaxRotate * -1);
            page.setPivotX(page.getWidth());
            page.setPivotY(page.getHeight());
        }else if(position <= 1){
            if(position < 0){
                /**
                 * (1)position是0到-1的变化,p1+position就是从1到0的变化
                 * (2)(p1 - mMinAlpha) * (p1 + position)就是(p1 - mMinAlpha)到0的变化
                 * (3)再加上一个mMinAlpha,就变为1到mMinAlpha的变化。
                 */
                float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position);
                page.setAlpha(factor);

                page.setRotation(mMaxRotate * position);

                //(4)position为width/2到width的变化
                page.setPivotX(page.getWidth() * 0.5f * (1 - position));
                page.setPivotY(page.getHeight());
            }else{
                //minAlpha到1的变化
                float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);
                page.setAlpha(factor);

                page.setRotation(mMaxRotate * position);
                page.setPivotX(page.getWidth() * 0.5f * (1 - position));
                page.setPivotY(page.getHeight());
            }
        }else{
            page.setAlpha(mMinAlpha);

            page.setRotation(mMaxRotate);
            page.setPivotX(0);
            page.setPivotY(page.getHeight());
        }
    }
}

2.5item布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorAccent"
    >

    <ImageView
        android:id="@+id/iv_page"
        android:layout_width="wrap_content"
        android:layout_height="260dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv"
        android:textSize="16dp"
        android:text="tag"
        android:layout_gravity="center"
        android:gravity="center"/>

</LinearLayout>

2.6Activity布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:background="#aadcff"
    android:clipChildren="false">

    <com.gdc.knowledge.highui.hightviewpager.MyViewPager
        android:id="@+id/view_Pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="60dp"
        android:layout_marginRight="60dp"
        android:clipChildren="false"/>

    <RadioGroup
        android:id="@+id/radio_group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="10dp"
        android:orientation="horizontal" />

</FrameLayout>

3.打赏鼓励

感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!

3.1微信打赏

在这里插入图片描述

3.2支付宝打赏

在这里插入图片描述

以上是关于02ViewPager高度自适应轮播图的主要内容,如果未能解决你的问题,请参考以下文章

02ViewPager高度自适应轮播图

轮播图js怎么设置图片自适应大小

轮播图如何自适应高度、宽度

element-ui中轮播图自适应图片高度

Flutter实现马蜂窝小红书自适应高度轮播图

Android使用ViewPager实现轮播图(自动和手动)