我设计具有多页的视图。我想上一页和下一页的边缘上显示像下面和实施2手指轻扫页面之间切换。ViewPager有一个和下一个页面边界
我尝试使用ViewPager
负页边距的建议here但只显示在屏幕上边缘,两者不能同时使用的一个。
可替代地,是没有什么办法可以定位我的外屏幕视图的一部分,然后动画它给它一个ViewPager
类型的效果。
我应该怎样做呢?谢谢 !
我设计具有多页的视图。我想上一页和下一页的边缘上显示像下面和实施2手指轻扫页面之间切换。ViewPager有一个和下一个页面边界
我尝试使用ViewPager
负页边距的建议here但只显示在屏幕上边缘,两者不能同时使用的一个。
可替代地,是没有什么办法可以定位我的外屏幕视图的一部分,然后动画它给它一个ViewPager
类型的效果。
我应该怎样做呢?谢谢 !
引用自己从a blog post on this subject:
第三种方法来自戴维·史密斯,受到广泛关注的书的Android食谱的合着者。他到一个完全不同的方向,使用自定义容器残疾儿童裁剪同时显示多个页面。
他published sample code显示在行动了整个事情。他的容器(
com.example.pagercontainer.PagerContainer
)包装ViewPager
并自行呼叫setClipChildren(false);
,因此即使ViewPager
只针对一个选定页面,但其他页面的坐标超出ViewPager
范围仍可见,只要它们在PagerContainer
之内即可。通过将ViewPager
的大小设置为小于PagerContainer
,ViewPager
可以将其页面调整为该大小,为其他页面留出空间。但是,PagerContainer
需要帮助点触摸事件,因为ViewPager
只能处理其自身可见边界上的滑动事件,而忽略任何可见边界的页面。
组的左和整个项目视图右侧填充。例如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>
然后设置为PageView
等于2 *(先前视图填充)负页边距
int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2, getResources().getDisplayMetrics());
mViewPager.setPageMargin(-margin);
可选。为第一个项目设置零左填充,为最后项目设置零右填充以隐藏空白边缘。您可以在PageAdapter
或Page
片段类中执行此操作。
@Sergey,我无法用你的解决方案做这个工作,你可以发布一个例子吗? thx – Marckaraujo
只需添加注释:使用此解决方案从第1页滑动到第2页时,页面3不在内存中,因此它会延迟显示。解决这个只是添加 - yourViewPager.setOffscreenPageLimit(2); –
我这样做,但它禁用最后一项的过度滚动效果。任何线索呢? – Swayam
我有一个类似的解决方案:
在离开viewpager组和右填充,例如20dp。也可以在viewpager上设置页面边距,例如一半的寻呼机填充。而且不要忘了禁用剪辑填充。
tilePager.setPadding(defaultGap, 0, defaultGap, 0);
tilePager.setClipToPadding(false);
tilePager.setPageMargin(halfGap);
提供了很好的解决方案。 – akash89
最简单最好的方法 –
要显示左,右页的预览设置以下两个值
viewpager.setClipToPadding(false)
viewpager.setPadding(left,0,right,0)
如果您需要在viewpager两个页面之间空间再加入viewpager.setPageMargin(INT)
这应该是正确的答案。我想也许这并不适用于以前版本的viewpager,但它现在起作用了。 –
它在最后一页的右侧和左侧添加了相同的边距。任何修复 –
简短和更清楚的答案。 –
从这里下载源代码(ViewPager with previous and next page boundaries)
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
与PagerSnapHelper(在V7支持库的25.1.0版新增),而不是经典ViewPager
一个小小的图书馆:
MetalRecyclerPagerView - 你可以在那里找到所有的代码和例子。
它主要由一个类文件组成:MetalRecyclerViewPager.java(和两个xml:attrs.xml和ids.xml)。
希望它可以帮助别人:)
,如果有人还在寻找解决办法,我已经定制的ViewPage去实现它,而无需使用负保证金,找到一个示例项目在这里https://github.com/44kksharma/Android-ViewPager-Carousel-UI 应该在大多数情况下工作,但你可以仍然定义页边距与 mPager.setPageMargin(margin in pixel);
“只显示在屏幕上,不能同时在一个边缘的同时进行。”你在第0页,你只看到第1页的一部分?也许你需要使用圆形寻呼机,例如,然后将页面始终设置为“中间”位置。看到这篇文章和评论:http://stackoverflow.com/a/8304474/1851478 – logray