自定义ViewPager中心当前项目,在适配器中具有自定义getPageWidth

时间:2016-03-30 12:21:55

标签: android android-viewpager android-custom-view centering

我有一个自定义ViewPager,就像一个Carousel,我希望能够在一个上显示多个页面。为此,我们有两个解决方案:

  • 使用边距setPageMargin()方法
  • 或者我们可以使用覆盖我的ViewPager适配器的getPageWidth方法。

第一个解决方案效果很好,但我希望能够精确确定当前页面的百分比。问题在于getPageWidth解决方案,我的当前页面在左侧移动。这是合乎逻辑的,因为她只占她以前尺寸的80%。所以我尝试覆盖我的自定义ViewPager的scrollTo函数,如下所示:

 @Override
    public void scrollTo(int x, int y) {
        x = (int) (x - (getWidth() - getWidth()*getAdapter().getPageWidth(getCurrentItem()))/2);
        super.scrollTo(x, y);
    }

它正在工作,但我不能像以前一样滚动,它只是表现得很奇怪,没有朝着好的方向前进,不要动手。 ..有没有任何解决方案可以让我有一个工作滚动和居中的当前页面?

这是我的适配器:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

import java.util.ArrayList;

public class CarouselAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener {
    private ArrayList<Entity> mData = new ArrayList<>();
    private ScaledRelativeLayout cur = null, next = null;

    private float scale;
    private MainActivity context;
    private FragmentManager fragmentManager;

    public CarouselAdapter(MainActivity context, FragmentManager fragmentManager, ArrayList<Entity> mData) {
        super(fragmentManager);
        this.fragmentManager = fragmentManager;
        this.context = context;
        this.mData = mData;
    }

    @Override
    public float getPageWidth(int position) {
        return (0.85f);
    }

    @Override
    public Fragment getItem(int position) {
        if (position == MainActivity.FIRST_PAGE) {
            scale = MainActivity.BIG_SCALE;
        } else {
            scale = MainActivity.SMALL_SCALE;
        }

        position = position % mData.size();

        Fragment fragment = CarouselFragment.newInstance(context, mData.get(position), position, scale);
        return fragment;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (positionOffset >= 0f && positionOffset <= 1f) {
            cur = getRootView(position);
            cur.setScaleBoth(MainActivity.BIG_SCALE - MainActivity.DIFF_SCALE * positionOffset);

            if (position < mData.size()-1) {
                next = getRootView(position +1);
                next.setScaleBoth(MainActivity.SMALL_SCALE + MainActivity.DIFF_SCALE * positionOffset);
            }
        }
    }

    @Override
    public void onPageSelected(int position) {}

    @Override
    public void onPageScrollStateChanged(int state) {}

    private ScaledRelativeLayout getRootView(int position) {
        return (ScaledRelativeLayout) fragmentManager.findFragmentByTag(this.getFragmentTag(position)).getView().findViewById(R.id.rootItem);
    }

    private String getFragmentTag(int position) {
        return "android:switcher:" + context.carousel.getId() + ":" + position;
    }
}

更无用,但这是我的MainActivity:

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;

import java.util.ArrayList;

public class MainActivity  extends FragmentActivity {
    public static int FIRST_PAGE;
    public final static float BIG_SCALE = 1.0f;
    public final static float SMALL_SCALE = 0.85f;
    public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;

    public CarouselViewPager carousel;
    private CarouselAdapter carouselAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FIRST_PAGE = mData.size()/2;
        carouselAdapter = new CarouselAdapter(this, this.getSupportFragmentManager(), mData);
        carousel = (CarouselViewPager) findViewById(R.id.carousel);
        carousel.setAdapter(carouselAdapter);
        carousel.addOnPageChangeListener(carouselAdapter);
        carousel.setCurrentItem(Math.round(FIRST_PAGE));
        carousel.setOffscreenPageLimit(3);
        carousel.setClipToPadding(false);
        carousel.setScrollDurationFactor(2.5f);
    }
}

编辑:

 root.post(new Runnable() {
            @Override
            public void run() {
                int width = root.getWidth();
                Log.w("Post", "Width : " + width + ", newWidth : " + (width * 0.8));
                // root.setPadding((int) (width * 0.125), 0, (int) (width * 0.125), 0);

                ViewPager.LayoutParams params = (ViewPager.LayoutParams) root.getLayoutParams();
                params.width = (int) (width * 0.8);
                root.setLayoutParams(params);
                root.requestLayout();
                root.forceLayout();
                root.invalidate();
            }
        });

此致

1 个答案:

答案 0 :(得分:9)

而不是setPageMargingetPageWidth您只需将填充设置为ViewPager即可。

<android.support.v4.view.ViewPager
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:clipToPadding="false" />

注意clipToPadding部分,显示其他页面非常重要。

如果要将宽度显示为屏幕的x%,可以使用Java

执行此操作
mRootView.post(new Runnable() {
    @Override
    public void run() {
        int w = mRootView.getWidth();
        mViewPager.setPadding(w * 0.25, 0, w * 0.25, 0);
        // 25% padding on either side so pages takes exactly 50% space
    }
});