Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

android - View Pager with previous and next item smaller in size with infinite scroll

Want to create the view pager same as following UI, applied custom transformer but not working.

enter image description here

ViewPager.java

public class MyViewPager extends ViewPager implements ViewPager.PageTransformer {
public static final String TAG = "MyViewPager";
private float MAX_SCALE = 0.0f;
private int mPageMargin;
private boolean animationEnabled=true;
private boolean fadeEnabled=false;
private  float fadeFactor=0.5f;


public MyViewPager(Context context) {
    this(context, null);
}

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    // clipping should be off on the pager for its children so that they can scale out of bounds.
    setClipChildren(false);
    setClipToPadding(false);
    // to avoid fade effect at the end of the page
    setOverScrollMode(2);
    setPageTransformer(false, this);
    setOffscreenPageLimit(3);
    mPageMargin = dp2px(context.getResources(), 50);
    setPadding(mPageMargin, mPageMargin, mPageMargin, mPageMargin);
}

public int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resource.getDisplayMetrics());
}
public void setAnimationEnabled(boolean enable) {
    this.animationEnabled = enable;
}

public void setFadeEnabled(boolean fadeEnabled) {
    this.fadeEnabled = fadeEnabled;
}

public void setFadeFactor(float fadeFactor) {
    this.fadeFactor = fadeFactor;
}

@Override
public void setPageMargin(int marginPixels) {
    mPageMargin = marginPixels;
// setPadding(mPageMargin, mPageMargin, mPageMargin, mPageMargin);
}

@Override
public void transformPage(View page, float position) {
    if (mPageMargin <= 0|| !animationEnabled)
        return;
    page.setPadding(mPageMargin / 3, mPageMargin / 3, mPageMargin / 3, mPageMargin / 3);

    if (MAX_SCALE == 0.0f && position > 0.0f && position < 1.0f) {
        MAX_SCALE = position;
    }
    position = position - MAX_SCALE;
    float absolutePosition = Math.abs(position);
    if (position <= -1.0f || position >= 1.0f) {
        if(fadeEnabled)
            page.setAlpha(fadeFactor);
        // Page is not visible -- stop any running animations

    } else if (position == 0.0f) {

        // Page is selected -- reset any views if necessary
        page.setScaleX((1 + MAX_SCALE));
        page.setScaleY((1 + MAX_SCALE));
        page.setAlpha(1);
    } else {
        page.setScaleX(1 + MAX_SCALE * (1 - absolutePosition));
        page.setScaleY(1 + MAX_SCALE * (1 - absolutePosition));
        if(fadeEnabled)
            page.setAlpha( Math.max(fadeFactor, 1 - absolutePosition));
    }
}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

UPDATE - if you want to make current page zoom use below PageTransformer

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

public class JavaActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    MyAdapter MyAdapter;

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

        myViewPager2 = findViewById(R.id.viewpager);

        MyAdapter = new MyAdapter(this);
        myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
        myViewPager2.setAdapter(MyAdapter);
        myViewPager2.setOffscreenPageLimit(3);

        float pageMargin = getResources().getDimensionPixelOffset(R.dimen.pageMargin);
        float pageOffset = getResources().getDimensionPixelOffset(R.dimen.offset);

        myViewPager2.setPageTransformer((page, position) -> {
            float myOffset = position * -(2 * pageOffset + pageMargin);
            if (position < -1) {
                page.setTranslationX(-myOffset);
            } else if (position <= 1) {
                float scaleFactor = Math.max(0.7f, 1 - Math.abs(position - 0.14285715f));
                page.setTranslationX(myOffset);
                page.setScaleY(scaleFactor);
                page.setAlpha(scaleFactor);
            } else {
                page.setAlpha(0);
                page.setTranslationX(myOffset);
            }
        });

    }
}

OUTPUT

![enter image description here

NOTE: you can download complete code from my GitHub repositories

Try this way

JavaActivity

import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.viewpager2.widget.ViewPager2;

public class JavaActivity extends AppCompatActivity {

    ViewPager2 myViewPager2;
    MyAdapter MyAdapter;

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

        myViewPager2 = findViewById(R.id.viewpager);

        MyAdapter = new MyAdapter(this);
        myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
        myViewPager2.setAdapter(MyAdapter);
        myViewPager2.setOffscreenPageLimit(3);

        float pageMargin= getResources().getDimensionPixelOffset(R.dimen.pageMargin);
        float pageOffset = getResources().getDimensionPixelOffset(R.dimen.offset);
        
        myViewPager2.setPageTransformer(new ViewPager2.PageTransformer() {
            @Override
            public void transformPage(@NonNull View page, float position) {
                float myOffset = position * -(2 * pageOffset + pageMargin);
                if (myViewPager2.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) {
                    if (ViewCompat.getLayoutDirection(myViewPager2) == ViewCompat.LAYOUT_DIRECTION_RTL) {
                        page.setTranslationX(-myOffset);
                    } else {
                        page.setTranslationX(myOffset);
                    }
                } else {
                    page.setTranslationY(myOffset);
                }
            }
        });
    }
}

activity_java layout file

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical"
                  tools:context=".JavaActivity">
    
        <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/viewpager"
                android:clipToPadding="false"
                android:clipChildren="false"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
    
    </LinearLayout>

>

MyAdapter

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private Context context;

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


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.row_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvName.setText(String.format("Row number%d", position));
        if (position % 2 ==0){
            holder.imgBanner.setBackgroundColor(Color.RED);
        }else {
            holder.imgBanner.setBackgroundColor(Color.GREEN);
        }
    }

    @Override
    public int getItemCount() {
        return 15;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;
        ImageView imgBanner;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvName);
            imgBanner = itemView.findViewById(R.id.imgBanner);
        }
    }
}

row_item layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_marginLeft="@dimen/pageMarginAndOffset"
             android:layout_marginRight="@dimen/pageMarginAndOffset"
             android:layout_height="match_parent"
             android:orientation="vertical">

    <ImageView
            android:id="@+id/imgBanner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorAccent"
            android:contentDescription="@string/app_name"/>

    <TextView
            android:id="@+id/tvName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            android:textStyle="bold"
            tools:text="Hello"/>

</RelativeLayout>

OUTPUT

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...