尝试过相册和水平滚动视图之后,我发现 View Pager 可以满足我的需求,但有一点小问题。View Pager 是否可以每页显示多个视图?
我知道 View Pager 每次滑动只能显示一个视图/页。我想知道是否可以限制我的视图宽度,这样紧随其后的第二个视图也会显示出来?
例如:我有3个视图,我希望屏幕显示视图1和部分视图2,这样用户就知道还有更多内容,可以向右滑动查看视图2。
|view 1|view 2|view 3|
|screen |
尝试过相册和水平滚动视图之后,我发现 View Pager 可以满足我的需求,但有一点小问题。View Pager 是否可以每页显示多个视图?
我知道 View Pager 每次滑动只能显示一个视图/页。我想知道是否可以限制我的视图宽度,这样紧随其后的第二个视图也会显示出来?
例如:我有3个视图,我希望屏幕显示视图1和部分视图2,这样用户就知道还有更多内容,可以向右滑动查看视图2。
|view 1|view 2|view 3|
|screen |
我发现了一个可能更简单的解决方案,可以通过为ViewPager指定负边距来实现。我在GitHub上创建了MultiViewPager项目,您可能想要查看一下:
尽管MultiViewPager需要一个子视图来指定维度,但其原则在于设置页面边距。
ViewPager.setPageMargin(
getResources().getDimensionPixelOffset(R.dimen.viewpager_margin));
然后我在我的 dimens.xml
文件中指定了这个尺寸:
<dimen name="viewpager_margin">-64dp</dimen>
android:layout_marginLeft="@dimen/viewpager_margin_fix"
android:layout_marginRight="@dimen/viewpager_margin_fix"
再次在 dimens.xml
中:
<dimen name="viewpager_margin_fix">32dp</dimen>
viewpager_margin_fix
维度是绝对 viewpager_margin
维度的一半。Mark Murphy在他的一篇有关这个问题的博客文章中提出了一个有趣的解决方案。虽然我最终在这个线程中使用了我自己的解决方案,但值得看看Dave Smith的代码,这也是Mark在博客文章中提到的:
警告!在采取这种方法之前,请注意此方法存在一些非常严重的问题,这些问题在本文末尾和下面的评论中都有提到。
最终实现效果如下:
它有效地通过将ViewPager
包装在FrameLayout
的子类中,并将其设置为特定大小,并调用setClipChildren(false)
来阻止Android剪切超出ViewPager
边界的视图,从而实现了你想要的效果。
在XML中,非常简单:
<com.example.pagercontainer.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#CCC">
<android.support.v4.view.ViewPager
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal" />
</com.example.pagercontainer.PagerContainer>
加入一些代码来处理来自 ViewPager
外部的触摸事件,并在滚动时使显示无效,就完成了。
话虽如此,虽然这通常很好用,但我注意到有一个边缘情况无法通过这种相当简单的构造解决:当在 ViewPager
上调用 setCurrentPage()
时。我找到的唯一解决方法是子类化 ViewPager
并让其 invalidate()
函数也使 PagerContainer
无效。
return 0.33f;
} - Ranjithkumar这是我得到它的方式:
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:gravity="center"
android:paddingLeft="36dp"
android:paddingRight="36dp"/>
在活动中,我使用这个:
markPager.setPageMargin(64);
希望对您有所帮助!
ViewPager
只出现在屏幕顶部,因为他们在xml文件中给它设定了一个固定大小。 android:layout_width="150dp"
android:layout_height="100dp"
这对我的目的不好,因为我正在寻找能够在整个屏幕上展开的东西。所以我将其更改为像您在此处看到的那样包装内容:
<com.example.nutrino_assignment.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCC">
<android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</com.example.nutrino_assignment.PagerContainer>
现在我失去了教程试图做的所有效果。使用@andro的答案,我能够同时显示多页:确切地说是2页!当前页和下一页。 通过以下方式覆盖实现:
@Override
public float getPageWidth(int position) {
return(0.9f);
}
那差不多是我需要的......(尽管我认为对于你所要求的内容已经足够了),但对于其他可能需要像我一样的东西的人:
对于解决方案的最后一部分,我使用了@Paul Lammertsma在这个答案中提出的想法。
在戴夫·史密斯的代码中,您将在onCreate
方法中找到此行:
//A little space between pages
pager.setPageMargin(15);
//A little space between pages
pager.setPageMargin(-64);
现在在第一页看起来:
|view 1|view 2|view 3|
|screen |
当在第二页时,页面看起来如下:
|view 1|view 2|view 3|
|screen |
viewPager.setPageMargin(-18);// adjust accordingly ,-means less gap
private class ImagePagerAdapter2 extends PagerAdapter {
private int[] mImages = new int[] {
R.drawable.add1,
R.drawable.add3,
R.drawable.add4,
R.drawable.add2,
};
@Override
public float getPageWidth(int position) {
return .3f;
}
调整返回值...较小的意味着更多的图像......0.3 表示每次至少有 3 张图像。
LayoutParams lp = new LayoutParams(width,height);
viewpager.setLayoutParams(lp);
在 XML 文件中使用此代码(主活动)
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="130dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
android:weightSum="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="130dp">
<com.wonderla.wonderla.muthootpathanamthitta.activity_muthootpathanm.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="100dip"
android:layout_height="100dip"/>
</com.wonderla.wonderla.muthootpathanamthitta.activity_muthootpathanm.PagerContainer>
</RelativeLayout>
</LinearLayout>
主活动 XML 文件中添加此代码
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="130dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
android:weightSum="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="130dp">
<com.wonderla.wonderla.muthootpathanamthitta.activity_muthootpathanm.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="100dip"
android:layout_height="100dip"/>
</com.wonderla.wonderla.muthootpathanamthitta.activity_muthootpathanm.PagerContainer>
</RelativeLayout>
</LinearLayout>
主活动代码
public class MainActivity extends Activity{
final Integer[] XMEN2= {R.mipmap.bookticket,R.mipmap.safty,R.mipmap.privacy};
private ArrayList<Integer> XMENArray2 = new ArrayList<Integer>();
PagerContainer mContainer;
int currentPage2 = 0;
private static int NUM_PAGES2 = 0;
ViewPager mPager2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initData2();}
private void initViews() {
mPager2 = (ViewPager)findViewById(R.id.viewpager);
mContainer = (PagerContainer)findViewById(R.id.pager_container);
mPager2.setOffscreenPageLimit(5);
mPager2.setPageMargin(15);
mPager2.setClipChildren(false);
}
private void initData2() {
for(int i=0;i<XMEN2.length;i++)
XMENArray2.add(XMEN2[i]);
mPager2.setAdapter(new Sliding_Adaptertwo(getActivity(),XMENArray2));
NUM_PAGES2 =XMEN2.length;
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage2 == NUM_PAGES2) {
currentPage2= 0;
}mPager2.setCurrentItem(currentPage2++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
@Override
public void run() {
handler.post(Update);
}
}, 3000, 3000);
}
}
Pager View pagercontainer 类
import android.content.Context;
import android.graphics.Point;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener {
private ViewPager mPager;
boolean mNeedsRedraw = false;
public PagerContainer(Context context) {
super(context);
init();
}
public PagerContainer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PagerContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//Disable clipping of children so non-selected pages are visible
setClipChildren(false);
//Child clipping doesn't work with hardware acceleration in Android 3.x/4.x
//You need to set this value here if using hardware acceleration in an
// application targeted at these releases.
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
try {
mPager = (ViewPager) getChildAt(0);
mPager.setOnPageChangeListener(this);
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager");
}
}
public ViewPager getViewPager() {
return mPager;
}
private Point mCenter = new Point();
private Point mInitialTouch = new Point();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w / 2;
mCenter.y = h / 2;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
//We capture any touches not already handled by the ViewPager
// to implement scrolling from a touch outside the pager bounds.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int)ev.getX();
mInitialTouch.y = (int)ev.getY();
default:
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
}
return mPager.dispatchTouchEvent(ev);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Force the container to redraw on scrolling.
//Without this the outer pages render initially and then stay static
if (mNeedsRedraw) invalidate();
}
@Override
public void onPageSelected(int position) { }
@Override
public void onPageScrollStateChanged(int state) {
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE);
}
}
和它的适配器
public class Sliding_Adaptertwo extends PagerAdapter {
private ArrayList<Integer> IMAGES;
private LayoutInflater inflater;
private Context context;
public Sliding_Adaptertwo(Context context, ArrayList<Integer> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getCount() {
return IMAGES.size();
}
@Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.sliding_layout, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
imageView.setImageResource(IMAGES.get(position));
view.addView(imageLayout, 0);
return imageLayout;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
@Override
public Parcelable saveState() {
return null;
}
}
适配器类的XML文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
>
<ImageView
android:id="@+id/image"
android:layout_width="90dp"
android:layout_height="90dp"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:scaleType="fitXY"
android:src="@drawable/ad1"
/>
</FrameLayout>
它运行良好