ViewPager with fixed width childs
android, android-viewpager
Solution
It is possible to scale the pages within the ViewPager with `FragmentPagerAdapter.getPageWidth`. You will need a custom FragmentPagerAdapter. If you return a number between 0 and 1, the pages are scaled down, width > 1 scales pages up accordingly. But this is not really good, because you can't scroll the image within the up-scaled page.
If you wrap the ImageView in a `HorizontalScrollView`, things are a bit better, you can scroll the images within pages, but the swipe gesture between pages is caught by the HorizontalScrollView if you are not very fast. See this video.
So the solution is truly to use a custom HorizontalScrollView (see `InterceptingHorizontalScrollView`) which disallows intercepting the onTouch event, but also allows it when the User scrolls to the end (See overidden `onOverScrolled`). See this video or the image below for the difference.
EDIT You don't need to override onInterceptTouchEvent, because HorizontalScrollView intercepts them by default (so scrolling the image has higher priority than paging.)
Finally, here's all the code:
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);
}
}
}
Problem
I need to design a `ViewPager` which able to pass childs with fixed width (e.g childs with 700dp width), Unfortunately the current version of `ViewPager` will automatically makes all childrens width to `MATCH_PARENT`, is there any way to add this functionality to `ViewPager`? My `ViewPager` layout: ``` <?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` childs layout: ``` <?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> ``` Thanks in Advance...