查看寻呼机,上一个和下一个项目的尺寸更小,无限滚动
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)。
vp2 是 ViewPager2
的实例这对我有用:
RecyclerView rv = (RecyclerView) vp2.getChildAt(0);
rv.setPadding(80, 0, 80, 0);
rv.setClipToPadding(false);
我使用 FragmentStateAdapter 并覆盖 getItemId()
和 containsItem()
以添加/删除片段。
结果在这里:
【讨论】:
【参考方案3】:您可以使用clipToPadding
并以编程方式将pageMargin
和padding
添加到您的viewpager
。
试试这样的-
viewpager.setClipToPadding(false);
viewpager.setPadding(40, 0, 70, 0);
viewpager.setPageMargin(20);
【讨论】:
这段代码和ViewPager有关,OP使用的是ViewPager2以上是关于查看寻呼机,上一个和下一个项目的尺寸更小,无限滚动的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xcode 项目中的 Scroll View 上无限滚动?