解決ViewPager setCurrentItem 時閃太快
ViewPager 使用 setCurrentItem 的時候,如果兩個頁面相聚比較遠,比如從第一個頁面跳到第六個頁面,就會閃一下,解決辦法就是把界面滑動的效果的 duration 設置為0,但是ViewPager 內部的 mScroller 無法正常獲得,所以可以嘗試采用 反射的方法:
先自定一個MScroller
方便調節 duration
public class MScroller extends Scroller {
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
public boolean noDuration;
public void setNoDuration(boolean noDuration) {
this.noDuration = noDuration;
}
public MScroller(Context context) {
this(context,sInterpolator);
}
public MScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
if(noDuration)
//界面滑動不需要時間間隔
super.startScroll(startX, startY, dx, dy, 0);
else
super.startScroll(startX, startY, dx, dy,duration);
}
}
定義一個輔助類
public class ViewPageHelper {
ViewPager viewPager;
MScroller scroller;
public ViewPageHelper(ViewPager viewPager) {
this.viewPager = viewPager;
init();
}
public void setCurrentItem(int item){
setCurrentItem(item,true);
}
public MScroller getScroller() {
return scroller;
}
public void setCurrentItem(int item, boolean somoth){
int current=viewPager.getCurrentItem();
//如果頁面相隔大于1,就設置頁面切換的動畫的時間為0
if(Math.abs(current-item)>1){
scroller.setNoDuration(true);
viewPager.setCurrentItem(item,somoth);
scroller.setNoDuration(false);
}else{
scroller.setNoDuration(false);
viewPager.setCurrentItem(item,somoth);
}
}
private void init(){
scroller=new MScroller(viewPager.getContext());
Class<ViewPager>cl=ViewPager.class;
try {
Field field=cl.getDeclaredField("mScroller");
field.setAccessible(true);
//利用反射設置mScroller域為自己定義的MScroller
field.set(viewPager,scroller);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
}
}
這樣每次設置頁面的時候,通過 helper 就可以自動選擇是否有時間間隔了。
但是這樣有點麻煩,每次還要手動改,而且使用TabLayout的話,它會自動調用ViewPager的方法,無法使用Helper,所以可以采用自定一個一個 ViewPager
public class SuperViewPager extends ViewPager {
private ViewPageHelper helper;
public SuperViewPager(Context context) {
this(context,null);
}
public SuperViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
helper=new ViewPageHelper(this);
}
@Override
public void setCurrentItem(int item) {
setCurrentItem(item,true);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
MScroller scroller=helper.getScroller();
if(Math.abs(getCurrentItem()-item)>1){
scroller.setNoDuration(true);
super.setCurrentItem(item, smoothScroll);
scroller.setNoDuration(false);
}else{
scroller.setNoDuration(false);
super.setCurrentItem(item, smoothScroll);
}
}
}
這樣用起來就很方便了。
fragment布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="@color/colorPrimary"
android:layout_height="match_parent">
<TextView
android:gravity="center"
android:textSize="27sp"
android:textColor="#ffffff"
android:layout_centerInParent="true"
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
MFragment
public class MFragemnt extends Fragment {
private String name="default";
public static MFragemnt newInstance(String name){
MFragemnt fragemnt=new MFragemnt();
fragemnt.name=name;
return fragemnt;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_test,container,false);
TextView textView=(TextView)view.findViewById(R.id.textview);
textView.setText(name);
return view;
}
}
activity 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="thereisnospon.viewpager.MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.support.design.widget.TabLayout>
<thereisnospon.viewpager.SuperViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"></thereisnospon.viewpager.SuperViewPager>
</LinearLayout>
這里使用了一個 tabLayout ,它是在 design 包里的
需要在 gradle 文件加:
compile 'com.android.support:design:23.4.0'
activity
public class MainActivity extends AppCompatActivity {
private TabLayout tablayout;
private SuperViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.viewPager = (SuperViewPager) findViewById(R.id.viewPager);
this.tablayout = (TabLayout) findViewById(R.id.tablayout);
viewPager.setAdapter(new PageAdapter(getSupportFragmentManager()));
tablayout.setupWithViewPager(viewPager);
}
public static class PageAdapter extends FragmentPagerAdapter{
public PageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public CharSequence getPageTitle(int position) {
return "P:"+position;
}
@Override
public Fragment getItem(int position) {
return MFragemnt.newInstance("Page:"+position);
}
@Override
public int getCount() {
return 5;
}
}
}
來自:http://www.jianshu.com/p/ae360ffcbcda
本文由用戶 gpyq6055 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!