我需要设计一个ViewPager
能够传递固定宽度的孩子(例如宽度为700dp的孩子),不幸的是当前版本的ViewPager
会自动使所有孩子的宽度达到MATCH_PARENT
有没有办法将此功能添加到ViewPager
?
我的ViewPager
布局:
<?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="wrap_content"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/some_id"
android:layout_width="match_parent"
android:layout_height="300dp"
android:overScrollMode="never" />
</LinearLayout>
ViewPager
孩子布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/banner_main_layout_container"
android:layout_width="700dp"
android:layout_height="match_parent"
android:background="#fff"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="some images"/>
</LinearLayout>
提前致谢...
答案 0 :(得分:6)
可以使用FragmentPagerAdapter.getPageWidth
缩放ViewPager中的页面。您将需要一个自定义FragmentPagerAdapter。如果返回0到1之间的数字,则缩小页面宽度&gt; 1相应地缩放页面。但这并不是很好,因为你不能在升级的页面中滚动图像。
如果将ImageView包装在HorizontalScrollView
中,事情会好一些,您可以在页面中滚动图像,但如果您不是很快,则可以通过HorizontalScrollView捕获页面之间的滑动手势。请参阅this video。
因此,解决方案是真正使用自定义HorizontalScrollView(请参阅InterceptingHorizontalScrollView
),它不允许拦截onTouch事件,但在用户滚动到最后时也允许它(请参阅覆盖onOverScrolled
)。有关差异,请参阅this video或下图
编辑您不需要覆盖onInterceptTouchEvent,因为HorizontalScrollView默认拦截它们(因此滚动图像的优先级高于分页。)
最后,这是所有代码:
<强> MainActivity.java 强>
public class MainActivity extends Activity {
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the ViewPager
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setPageMargin(30);
mViewPager.setAdapter(new ImagePagerAdapter(getFragmentManager()));
}
private class ImagePagerAdapter extends FragmentPagerAdapter {
public ImagePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
switch(i) {
case 0:
return ImageFragment.newInstance(R.drawable.forest1);
case 1:
return ImageFragment.newInstance(R.drawable.forest2);
case 2:
return ImageFragment.newInstance(R.drawable.forest3);
default:
return ImageFragment.newInstance(R.drawable.ic_launcher);
}
}
@Override
public int getCount() {
return 3;
}
@Override
public float getPageWidth(int position)
{
// Here it is possible to scale page width
return super.getPageWidth(position);
}
}
}
<强> activity_main.xml中强>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
<强> ImageFragment.java 强>
public class ImageFragment extends Fragment {
private static final String ARG_PARAM1 = "image_resid";
private int mImageResId;
public static ImageFragment newInstance(int image_resid) {
ImageFragment fragment = new ImageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PARAM1, image_resid);
fragment.setArguments(args);
return fragment;
}
public ImageFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mImageResId = getArguments().getInt(ARG_PARAM1);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_image, container, false);
ImageView imageView = (ImageView)v.findViewById(R.id.imageView);
imageView.setImageResource(mImageResId);
return v;
}
}
<强> fragment_image.xml 强>
<com.gyebro.viewpagertest.InterceptingHorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="600dp"
android:layout_height="match_parent"
tools:context="com.gyebro.viewpagertest.ImageFragment">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:id="@+id/imageView"
android:src="@drawable/forest1" />
</com.gyebro.viewpagertest.InterceptingHorizontalScrollView>
InterceptingHorizontalScrollView.java
public class InterceptingHorizontalScrollView extends HorizontalScrollView {
public InterceptingHorizontalScrollView(Context context) {
super(context);
}
public InterceptingHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InterceptingHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/*@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (getParent() != null) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
}
return super.onInterceptTouchEvent(ev);
}*/
@Override
protected void onOverScrolled (int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX,scrollY,clampedX,clampedY);
// if clampedX == true, we've reached the end of the HorizontalScrollView so
// allow parent to intercept
if(clampedX) {
Log.d("InterceptingHorizontalScrollView", "Reached the end, allowing interception");
getParent().requestDisallowInterceptTouchEvent(false);
}
}
}
答案 1 :(得分:1)
您真正想要的是HorizontalScrollView
内的ViewPager
。这需要自定义触摸处理,因此您希望使用类似此类的内容:InterceptingHorizontalScrollView
要使InterceptingHorizontalScrollView
ViewPager
工作,您必须覆盖onOverScrolled
:
@Override
protected void onOverScrolled (int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX,scrollY,clampedX,clampedY);
if(clampedX) {
getParent().requestDisallowInterceptTouchEvent(false);
}
}
感谢Gyebro的提示。^
您的ViewPager
子布局如下所示:
<com.tumblr.widget.InterceptingHorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/banner_main_layout_container"
android:layout_width="700dp"
android:layout_height="match_parent"
android:background="#fff"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="some images"/>
</LinearLayout>
</com.tumblr.widget.InterceptingHorizontalScrollView>
答案 2 :(得分:1)
你可以覆盖PagerAdapter的getWidth方法,如果这没有帮助,请看看: http://commonsware.com/blog/2012/08/20/multiple-view-viewpager-options.html
最重要的是尝试this example,效果很好! 只是沿着整个例子。
答案 3 :(得分:-1)
ImageView
听起来不错。在肖像模式下会是什么样子?如果您不想让ViewPager本身变小,即您希望从屏幕的绝对侧滑动ImageViews
,则必须使项目出现强>小。
可以通过创建另外两个LinearLayouts
作为间隔符来完成模仿。然后看起来好像你的物品有特定的宽度。
这是一个示例(使用TextView):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:background="#FFF"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<TextView
android:layout_weight="10"
android:background="#333"
android:textColor="#FFF"
android:textSize="50sp"
android:gravity="center"
android:text="HELLO"
android:layout_width="0dp"
android:layout_height="match_parent" />
<LinearLayout
android:background="#FFF"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
这看起来像这样:
答案 4 :(得分:-1)
将视图寻呼机的页边距设置为负值。这将强制页面进入视图寻呼机。请注意,它也会导致重叠,因此您将在视图寻呼机中看到下一个/上一个元素的一部分。
答案 5 :(得分:-1)
ViewPager通过 getPageWidth 方法查询每个页面宽度的给定适配器。所以你可以返回所需的宽度。这就是支持库v13的实现方式:
public class AdapterFragment extends FragmentPagerAdapter
{
// other methods
@Override
public float getPageWidth(int position)
{
return 700f; // this is 700px, you can convert from DP or SP using TypedValues
}
}
您还可以根据位置为不同的页面返回不同的宽度。