查看寻呼机,上一个和下一个项目的尺寸更小,无限滚动

Posted

技术标签:

【中文标题】查看寻呼机,上一个和下一个项目的尺寸更小,无限滚动【英文标题】:View Pager with previous and next item smaller in size with infinite scroll 【发布时间】:2020-01-22 05:51:39 【问题描述】:

想要创建与以下 UI 相同的视图分页器,应用了自定义转换器但无法正常工作。

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));
    


【问题讨论】:

@AlbertVilaCalvo 它不是重复的两个问题都是针对不同的观点 @NileshRathod 我没有找到任何合适的解决方案,你有什么解决方案吗? @mdDroid 你检查了我下面的答案***.com/a/58056129/7666442 请查看我的回答***.com/a/67771069/3586084 【参考方案1】:

更新 - 如果你想在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);
            
        );

    

输出

注意:您可以从my GitHub repositories下载完整代码

试试这个方法

Java活动

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 布局文件

    <?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_
                  android:layout_
                  android:orientation="vertical"
                  tools:context=".JavaActivity">
    
        <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/viewpager"
                android:clipToPadding="false"
                android:clipChildren="false"
                android:layout_
                android:layout_/>
    
    </LinearLayout>

>

我的适配器

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 布局

<?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_
             android:layout_marginLeft="@dimen/pageMarginAndOffset"
             android:layout_marginRight="@dimen/pageMarginAndOffset"
             android:layout_
             android:orientation="vertical">

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

    <TextView
            android:id="@+id/tvName"
            android:layout_
            android:layout_
            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>

输出

【讨论】:

谢谢!我一直在尝试使用ViewPager2 实现轮播几个小时,但没有成功。 我认为您不需要在ViewPager 上设置clipToPadding="false",因为它没有任何填充。另外,我认为您也不需要clipChildren="false",因为您没有将任何项目缩放超过100%(即,您没有在ViewPager 之外绘制)。如果我删除它们,在您的 GitHub 代码上没有任何变化。如果这些属性没用,我建议删除它们。 @AlbertVilaCalvo 好的,我会删除它 另一件事:您将 offscreenPageLimit 设置为 3。这意味着在 每个 侧保留了 3 个项目(共 6 个),即使您只显示 1每边的额外项目。除非您需要这样做,否则您可以将此数字降低到 2 甚至 1(一切正常)。 滚动后不知何故留下了空白空间【参考方案2】:

使用 ViewPager2(其中包含 RecyclerView)。

vp2ViewPager2

的实例

这对我有用:

RecyclerView rv = (RecyclerView) vp2.getChildAt(0);
rv.setPadding(80, 0, 80, 0);
rv.setClipToPadding(false);

我使用 FragmentStateAdapter 并覆盖 getItemId()containsItem() 以添加/删除片段。

结果在这里:

【讨论】:

【参考方案3】:

您可以使用clipToPadding 并以编程方式将pageMarginpadding 添加到您的viewpager。 试试这样的-

viewpager.setClipToPadding(false);
viewpager.setPadding(40, 0, 70, 0);
viewpager.setPageMargin(20);

【讨论】:

这段代码和ViewPager有关,OP使用的是ViewPager2

以上是关于查看寻呼机,上一个和下一个项目的尺寸更小,无限滚动的主要内容,如果未能解决你的问题,请参考以下文章

居中和滚动 UIScrollView 内容,尺寸更大或更小

如何实现无限滚动列表视图

如何在 Xcode 项目中的 Scroll View 上无限滚动?

NestedScrollView 问题中的可滚动寻呼机内容

如何在移动时调整 UIView 的大小,就像 SnapGuide 一样?

iPython 是不是具有在寻呼机中查看变量的内置支持? [复制]