天天看點

Viewpager自定義輪播特效(仿京東超市 休閑零食 頭部輪播)

要做類似這樣的效果:(京東---京東超市---休閑零食)

Viewpager自定義輪播特效(仿京東超市 休閑零食 頭部輪播)

做出來是這樣的:

Viewpager自定義輪播特效(仿京東超市 休閑零食 頭部輪播)

    接下來直接上代碼

頁面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"

    android:orientation="vertical"
    tools:context=".MainActivity">

    <!--android:clipChildren="false"-->

    <android.support.v4.view.ViewPager
        android:id="@+id/main_viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"

        android:layout_weight="3"
        android:clipToPadding="false"
        android:paddingRight="24dp">
        <!--android:layout_marginRight="24dp"-->

    </android.support.v4.view.ViewPager>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="7">

    </RelativeLayout>
</LinearLayout>
           

這裡注意

clipToPadding這個屬性  用法和原因請自行百度  
           
clipChildren屬性也請自行百度   這裡兩個屬性用一個就行了
           

然後Activity

package com.huaxia.mytestviewpager;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

import com.huaxia.mytestviewpager.adapter.MyViewPagerAdapter;
import com.huaxia.mytestviewpager.widget.MyPagerTransformer;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ViewPager main_viewpager;

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

        main_viewpager = (ViewPager) findViewById(R.id.main_viewpager);


        ArrayList<Integer> imageViews = new ArrayList<>();
        imageViews.add(Color.parseColor("#FF0000"));
        imageViews.add(Color.parseColor("#00FF00"));
        imageViews.add(Color.parseColor("#0000FF"));
        imageViews.add(Color.parseColor("#FFFF00"));
        imageViews.add(Color.parseColor("#00FFFF"));
        imageViews.add(Color.parseColor("#FF00FF"));

        initViewPager(imageViews);


    }

    private void initViewPager(ArrayList<Integer> imageViews) {
        main_viewpager.setOffscreenPageLimit(5);

        main_viewpager.setPageTransformer(false, new MyPagerTransformer());

        MyViewPagerAdapter myViewPagerAdapter = new MyViewPagerAdapter(this);
        main_viewpager.setAdapter(myViewPagerAdapter);
        myViewPagerAdapter.setList(imageViews);


    }
}
           

然後繼承的ViewPagerAdapter

package com.huaxia.mytestviewpager.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.ArrayList;

/**
 * @Author:JiaoHaoKang
 * @E-mail:[email protected]
 * @Date:2019/6/18
 * @Description:
 */
public class MyViewPagerAdapter extends PagerAdapter {

    private Context context;
    private ArrayList<Integer> list = new ArrayList<>();


    public MyViewPagerAdapter(Context context) {
        this.context = context;
    }

    public void setList(ArrayList<Integer> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    @Override

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

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

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        ImageView imageView = new ImageView(context);
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        imageView.setBackgroundColor(list.get(position % list.size()));
        container.addView(imageView);
        return imageView;
    }

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

然後繼承的PageTransformer

package com.huaxia.mytestviewpager.widget;

import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;

/**
 * @Author:JiaoHaoKang
 * @E-mail:[email protected]
 * @Date:2019/6/18
 * @Description:
 */
public class MyPagerTransformer implements ViewPager.PageTransformer {

    /*private static final float MIN_SCALE = 0.85f;
    private static final float MIN_ALPHA = 0.5f;

    @Override
    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();
        if (position < -1) {
            view.setAlpha(0);
        } else if (position <= 1) {
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageHeight * (1 - scaleFactor) / 2;
            if (position < 0) {
                view.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                view.setTranslationX(-horzMargin + vertMargin / 2);
            }
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

            view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
        } else {
            view.setAlpha(0);
        }
    }
*/
/*
    private  static final float ROT_MAX=20.0f;
    private  float mRot;
    @Override
    public void transformPage(View view, float position) {
        if (position<-1){
            view.setRotation(0);
        }else if (position<=1){
            //     if (position<0){
            //      mRot=(ROT_MAX*position);
            // view.setPivotX();
            //    view.setPivotX(view.getMeasuredWidth()*0.5f);
            //     view.setPivotY(view.getMeasuredHeight());
            //    view.setRotation(mRot);
            //   }else {
            mRot=(ROT_MAX*position);
            view.setPivotX(view.getMeasuredWidth()*0.5f);
            view.setPivotY(view.getMeasuredHeight());
            view.setRotation(mRot);
            // }
        }else{
            view.setRotation(0);
        }

    }

*/
  /*  private  static final float MIN_SCALE=0.75f;
    @Override
    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();

        if (position<-1){
            view.setAlpha(0);
        }else if(position<=0){
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);
        }else if (position<=1){
            view.setAlpha(1-position);
            view.setTranslationX(pageWidth*-position);

            float scaleFactor=MIN_SCALE+(1-MIN_SCALE)*(1-Math.abs(position));
            view.setScaleY(scaleFactor);
            view.setScaleY(scaleFactor);
        }else{
            view.setAlpha(0);
        }

    }
*/


    private float interval = 24;//間距

    /**
     * @param view
     * @param v    ? 玄學算數動不得
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void transformPage(@NonNull View view, float v) {
        int width = view.getWidth();

        if (v <= -1) {
            //                                  第負一張
            //具體實作,此時page在界面的左邊并且已經不顯示在目前界面
            view.setTranslationX(-width + -width);
            view.setTranslationZ(0);
        } else if (v <= 0) {
            //具體實作,此時page正從中間往左側移動  第一張

            view.setTranslationX(0);                    //水準位移
            view.setTranslationZ(4 + v);                //浮動
            view.setScaleY((float) -((float) 1 - -0.1 * (v)));   //垂直縮放
            view.setScaleX(1);
        } else if (v <= 1) {
            //具體實作,此時page正從右側往中間移動   第二張

            //Math.negateExact
            view.setTranslationX(-width * (v - 1) - width + interval + ((v - 1) * interval));
            view.setTranslationZ(2 + v);
            view.setScaleY((float) ((float) 0.9 - -0.1 * (1 - v)));
            float scaleX = view.getScaleX();
            //view.setScaleX((float) ((float) 1 - -0.1 * (1 - v)));  //和布局上 android:clipToPadding="false"沖突???
        } else if (v <= 2) {
            //                                      第三張

            view.setTranslationX((-width) * (v - 2) - width + -width + interval + interval + ((v - 2) * interval));
            view.setTranslationZ(0 + v);
            view.setScaleY((float) ((float) 0.8 - -0.1 * (2 - v)));
        } else if (v <= 3) {
            //                                       第四張

            view.setTranslationX((-width) * (v - 3) - width + -width + -width + interval + interval + interval + ((v - 3) * interval));
            view.setTranslationZ((-3 + v));
            view.setScaleY((float) ((float) 0.7 - -0.1 * (3 - v)));
        } else {
            //具體實作,此時page在界面的右邊并且已經不顯示在目前界面
            view.setTranslationX(width);
            view.setTranslationZ(0);
        }

    }
}
           

這個PageTransformer裡面注釋了還有從别的地方複制來的一些特效具體路徑忘了是以不放連結了

最後可能是存在一個Bug  就是注釋的:

view.setScaleX((float) ((float) 1 - -0.1 * (1 - v)));  //和布局上 android:clipToPadding="false"沖突???
           

這行   這裡用view.setScaleX的話回和clipToPadding和clipChildren這兩個屬性有沖突 指着兩個屬性失效 現在也不找原因了等閑的時候再找吧 ,  如果有大佬知道原因 歡迎評論留言.   

                                                                                                                                  --2019年6月21日 11:40:32