2016-03-30 55 views
0

我有一个自定义ViewPager行为像一个旋转木马,事情是我想能够显示一个多页。要做到这一点,我们有2个解决方案:自定义ViewPager中心当前项目与适配器中的自定义getPageWidth

  • 使用边缘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); 
    } 

它的工作,但因为之前,我不能滚动,它只是在表演确实很奇怪,不好的方向走,不要” t按照手指...有任何解决方案,让我有一个工作滚动和居中当前页面?

这里是我的适配器:

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(); 
      } 
     }); 

问候

回答

8

代替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 
    } 
}); 
+0

您的解决方案的伟大工程,谢谢!我只是有一个问题,是否真的使用线程来做到这一点?我的意思是设置一个填充,我们可以在主线程上做到这一点,或者它是可怕的? – zed13

+0

'mRootView.getWidth();'不会工作,除非视图已经被创建,并且它的宽度是由Android计算的。这不是一个单独的线程,它在UI线程上运行,但只是延迟到完全创建“mRootView”。如果你想 – Sourabh

+0

,你可以使用'screenWidth'来替代这个哦,是的,你说得对,我忘记了,再次感谢这些信息。祝你今天愉快。 – zed13