android - 具有固定宽度子项的 ViewPager

标签 android android-viewpager

我需要设计一个 ViewPager 能够传递固定宽度的 child (例如宽度为 700dp 的 child ),不幸的是 ViewPager 的当前版本会自动生成所有 child 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>

提前致谢...

最佳答案

可以使用 FragmentPagerAdapter.getPageWidth 在 ViewPager 中缩放页面。您将需要一个自定义的 FragmentPagerAdapter。如果返回 0 到 1 之间的数字,则页面会缩小,宽度 > 1 会相应地放大页面。但这并不是很好,因为您无法在放大的页面中滚动图像。

如果将 ImageView 包裹在 Horizo​​ntalScrollView 中,情况会好一些,您可以在页面内滚动图像,但如果您的速度不是很快,则页面之间的滑动手势会被 Horizo​​ntalScrollView 捕获.参见 this video .

所以解决方案是真正使用自定义 Horizo​​ntalScrollView(参见 InterceptingHorizo​​ntalScrollView),它不允许拦截 onTouch 事件,但在用户滚动到末尾时也允许它(参见覆盖 onOverScrolled)。参见 this video或下图的区别。

编辑 你不需要覆盖 onInterceptTouchEvent,因为 Horizo​​ntalScrollView 默认拦截它们(因此滚动图像比分页具有更高的优先级。)

最后,这是所有代码:

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>

拦截Horizo​​ntalScrollView.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);
        }
    }
}

关于android - 具有固定宽度子项的 ViewPager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23280679/

相关文章:

android - 找不到符号类 BaseAdapter

java - 如何在删除 fragment 时动态更新ViewPager

android - ViewPager多次调用--Android

android - ViewPager 内的 ViewPager。如何水平滚动父寻呼机而不是滚动子寻呼机,但保持子寻呼机垂直滚动?

android - Android无法解析id

java - 按下时滑动 TabLayout 更改选项卡的背景颜色

java - 我正在尝试从链接下载图像并将其显示在 ImageView 中,但行 imgView.setImageBitmap(myImg);抛出一些错误

java - 抽屉导航监听器不在 fragment 中工作

android - 如何刷新 View 页面中的 fragment ?

android - 查看寻呼机和 ListView