具有上一页和下一页边界的 ViewPager

我正在设计一个具有多个页面的视图。我希望上一个和下一个页面的边缘显示如下,并实现两个手指滑动页面之间切换。

enter image description here

我尝试使用负页边距的 ViewPager作为建议的 给你,但它只显示屏幕上的一个边缘,而不是同时两个。

或者,有没有办法我可以定位我的部分屏幕外的视图,然后动画它给它一个 ViewPager类型的效果。

我该怎么做呢? 谢谢!

105147 次浏览

引用我自己从 一篇关于这个主题的博客文章:

第三种方法来自戴夫 · 史密斯,他是广受好评的《安卓食谱》一书的合著者。他走向了一个非常不同的方向,使用一个自定义容器,该容器禁用儿童剪辑,以便一次显示多个页面。

他的 ViewPager1显示了整个过程。他的容器(com.example.pagercontainer.PagerContainer)包装了 ViewPager并对自身调用 setClipChildren(false);,因此即使 ViewPager集中在一个选定的页面上,其他具有超出 ViewPager边界的坐标的页面仍然可见,只要它们适合 PagerContainer。通过调整 ViewPagerPagerContainer小的尺寸,ViewPager可以调整它的页面大小,为其他页面留出可见的空间。不过,PagerContainer需要在触摸事件方面提供一些帮助,因为 ViewPager只会在自己的可见边界上处理滑动事件,忽略任何侧面可见的页面。

enter image description here

  1. 为整个项目视图设置左右填充。示例 xml (page _ item.xml) :

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"/>
    
    
    <TextView
    android:id="@+id/text1"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge" />
    
    
    </LinearLayout>
    
  2. Then set negative page margin for PageView equal to 2*(previous view padding)

    int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2,     getResources().getDisplayMetrics());
    mViewPager.setPageMargin(-margin);
    
  3. Optional. Set zero left padding for first item and zero right padding to last item to hide empty edges. You may do this in the PageAdapter or Page fragment class.

我有一个类似的解决方案:

在浏览器上设置左右填充,例如20dp。也要在视图页上设置页边距,例如页面填充的一半。不要忘记禁用剪辑填充。

tilePager.setPadding(defaultGap, 0, defaultGap, 0);
tilePager.setClipToPadding(false);
tilePager.setPageMargin(halfGap);

若要显示左页和右页的预览,请设置以下两个值

viewpager.setClipToPadding(false)
viewpager.setPadding(left,0,right,0)

如果在视图页面中两个页面之间需要空间,那么添加 viewpager.setPageMargin (int)

Android ViewPager-显示左右页面预览

从这里下载源代码(具有上一页和下一页边界的 ViewPager)

MainActivity.java

package com.deepshikha.viewpager;


import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.view.ViewGroup;


import java.util.ArrayList;
import java.util.List;


public class MainActivity extends FragmentActivity {


ViewPager pager;
MyPageAdapter obj_adapter;
String str_device;


@Override


public void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();




}


private void init() {
pager = (ViewPager) findViewById(R.id.viewpager);
differentDensityAndScreenSize(getApplicationContext());
List<Fragment> fragments = getFragments();
pager.setAdapter(obj_adapter);
pager.setClipToPadding(false);




if (str_device.equals("normal-hdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-mdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-xhdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-xxhdpi")){
pager.setPadding(180, 0, 180, 0);
}else if (str_device.equals("normal-xxxhdpi")){
pager.setPadding(180, 0, 180, 0);
}else if (str_device.equals("normal-unknown")){
pager.setPadding(160, 0, 160, 0);
}else {


}


obj_adapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
pager.setPageTransformer(true, new ExpandingViewPagerTransformer());
pager.setAdapter(obj_adapter);
}


class MyPageAdapter extends FragmentPagerAdapter {


private List<Fragment> fragments;


public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {


super(fm);


this.fragments = fragments;


}


@Override


public Fragment getItem(int position) {


return this.fragments.get(position);


}


@Override


public int getCount() {


return this.fragments.size();


}


}


private List<Fragment> getFragments() {


List<Fragment> fList = new ArrayList<Fragment>();


fList.add(MyFragment.newInstance("Fragment 1",R.drawable.imags));
fList.add(MyFragment.newInstance("Fragment 2",R.drawable.image1));
fList.add(MyFragment.newInstance("Fragment 3",R.drawable.image2));
fList.add(MyFragment.newInstance("Fragment 4",R.drawable.image3));
fList.add(MyFragment.newInstance("Fragment 5",R.drawable.image4));


return fList;


}


public int differentDensityAndScreenSize(Context context) {
int value = 20;
String str = "";
if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "small-ldpi";
// Log.e("small 1","small-ldpi");
value = 20;
break;
case DisplayMetrics.DENSITY_MEDIUM:
str = "small-mdpi";
// Log.e("small 1","small-mdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_HIGH:
str = "small-hdpi";
// Log.e("small 1","small-hdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XHIGH:
str = "small-xhdpi";
// Log.e("small 1","small-xhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XXHIGH:
str = "small-xxhdpi";
// Log.e("small 1","small-xxhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
str = "small-xxxhdpi";
//Log.e("small 1","small-xxxhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_TV:
str = "small-tvdpi";
// Log.e("small 1","small-tvdpi");
value = 20;
break;
default:
str = "small-unknown";
value = 20;
break;
}


} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "normal-ldpi";
// Log.e("normal-ldpi 1","normal-ldpi");
str_device = "normal-ldpi";
value = 82;
break;
case DisplayMetrics.DENSITY_MEDIUM:
// Log.e("normal-mdpi 1","normal-mdpi");
str = "normal-mdpi";
value = 82;
str_device = "normal-mdpi";
break;
case DisplayMetrics.DENSITY_HIGH:
// Log.e("normal-hdpi 1","normal-hdpi");
str = "normal-hdpi";
str_device = "normal-hdpi";
value = 82;
break;
case DisplayMetrics.DENSITY_XHIGH:
//Log.e("normal-xhdpi 1","normal-xhdpi");
str = "normal-xhdpi";
str_device = "normal-xhdpi";
value = 90;
break;
case DisplayMetrics.DENSITY_XXHIGH:
// Log.e("normal-xxhdpi 1","normal-xxhdpi");
str = "normal-xxhdpi";
str_device = "normal-xxhdpi";
value = 96;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
//Log.e("normal-xxxhdpi","normal-xxxhdpi");
str = "normal-xxxhdpi";
str_device = "normal-xxxhdpi";
value = 96;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("DENSITY_TV 1","normal-mdpi");
str = "normal-tvdpi";
str_device = "normal-tvmdpi";
value = 96;
break;
default:
// Log.e("normal-unknown","normal-unknown");
str = "normal-unknown";
str_device = "normal-unknown";
value = 82;
break;
}
} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "large-ldpi";
// Log.e("large-ldpi 1","normal-ldpi");
value = 78;
break;
case DisplayMetrics.DENSITY_MEDIUM:
str = "large-mdpi";
//Log.e("large-ldpi 1","normal-mdpi");
value = 78;
break;
case DisplayMetrics.DENSITY_HIGH:
//Log.e("large-ldpi 1","normal-hdpi");
str = "large-hdpi";
value = 78;
break;
case DisplayMetrics.DENSITY_XHIGH:
// Log.e("large-ldpi 1","normal-xhdpi");
str = "large-xhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXHIGH:
//Log.e("large-ldpi 1","normal-xxhdpi");
str = "large-xxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
// Log.e("large-ldpi 1","normal-xxxhdpi");
str = "large-xxxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("large-ldpi 1","normal-tvdpi");
str = "large-tvdpi";
value = 125;
break;
default:
str = "large-unknown";
value = 78;
break;
}


} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
// Log.e("large-ldpi 1","normal-ldpi");
str = "xlarge-ldpi";
value = 125;
break;
case DisplayMetrics.DENSITY_MEDIUM:
// Log.e("large-ldpi 1","normal-mdpi");
str = "xlarge-mdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_HIGH:
//Log.e("large-ldpi 1","normal-hdpi");
str = "xlarge-hdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XHIGH:
// Log.e("large-ldpi 1","normal-hdpi");
str = "xlarge-xhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXHIGH:
// Log.e("large-ldpi 1","normal-xxhdpi");
str = "xlarge-xxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
// Log.e("large-ldpi 1","normal-xxxhdpi");
str = "xlarge-xxxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("large-ldpi 1","normal-tvdpi");
str = "xlarge-tvdpi";
value = 125;
break;
default:
str = "xlarge-unknown";
value = 125;
break;
}
}


return value;
}
}

不久前,我需要这样的功能,并准备了一个小型库,它使用 RecyclerView寻呼机快照助手(在版本25.1.0的 v7支持库中添加) ,而不是经典的 ViewPager:

MetalReviclePagerView -您可以在那里找到所有的代码和示例。

它主要由一个类文件 Metal迴 clViewPager.java(以及两个 xml: XmlXml)组成。

希望对某些人有所帮助:)

如果有人仍然在寻找解决方案,我已经定制了 ViewPage 来实现它,而不使用负边距,在这里找到一个示例项目。这里是一个 https://github.com/44kksharma/android-viewpager-carousel-ui 它应该工作在大多数情况下,但您仍然可以定义页边距 mPager.setPageMargin(margin in pixel);

Carousel ViewPager 片段

    ViewPager viewPager = findViewById(R.id.viewPager);
TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(this,getSupportFragmentManager());
viewPager.setAdapter(tabPagerAdapter);
// Disable clip to padding
viewPager.setClipToPadding(false);
// set padding manually, the more you set the padding the more you see of prev & next page
viewPager.setPadding(40, 0, 40, 0);
// sets a margin b/w individual pages to ensure that there is a gap b/w them
viewPager.setPageMargin(20);

Carousel ViewPager