編輯:關於Android編程
每當viewpager上一個可見或依附的頁面發生了滾動事件就會調用PageTransformer,這讓應用可以使用自定義transformation讓viewpager某一個頁面視圖上實現某些特定的動畫屬性。
但是這樣的屬性動畫只能支持到android3.0版本或以上,在早期的版本上設置viewpager的PageTransformer會被忽略。
transformPage 應用屬性動畫到一個指定的頁面
void transformPage (View page, float position)
package com.example.simple.pagertransformdemo; public class MainActivity extends AppCompatActivity { private int imgIds[] = {R.drawable.img_1, R.drawable.img_2, R.drawable.img_3}; private ListviewList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); for (int i = 0; i < 3; i++) { View rootView = View.inflate(MainActivity.this, R.layout.item_pager, null); ImageView imageView = (ImageView) rootView.findViewById(R.id.pager_iv); imageView.setImageResource(imgIds[i]); TextView textView = (TextView) rootView.findViewById(R.id.pager_tv); textView.setText(String.valueOf(i)); viewList.add(i, rootView); } ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new MyAdapter()); } private class MyAdapter extends PagerAdapter { @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position)); return viewList.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position)); } } }
我們多加了一行代碼
viewPager.setPageTransformer(true ,new ZoomInTransform());
看看這這句代碼的作用
看源碼也可以得出
public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) { if (Build.VERSION.SDK_INT >= 11) { final boolean hasTransformer = transformer != null; final boolean needsPopulate = hasTransformer != (mPageTransformer != null); mPageTransformer = transformer; setChildrenDrawingOrderEnabledCompat(hasTransformer); if (hasTransformer) { //reverseDrawingOrder等於true時為倒序,false為正序 mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD; } else { mDrawingOrder = DRAW_ORDER_DEFAULT; } if (needsPopulate) populate(); } }
將 reverseDrawingOrder 改爲 false 看看效果
viewPager.setPageTransformer(false ,new ZoomInTransform());
再看看ZoomInTransform的代碼就一目了然了
public class ZoomInTransform implements ViewPager.PageTransformer { public static final String TAG = "simple_PagerTransform"; @Override public void transformPage(View page, float position) { int width = page.getWidth(); int height = page.getHeight(); //這裏只對右邊的view做了操作 if (position > 0 && position <= 1) {//right scorlling //position是1.0->0,但是沒有等於0 Log.e(TAG, "right----position====" + position); //設置該view的X軸不動 page.setTranslationX(-width * position); //設置縮放中心點在該view的正中心 page.setPivotX(width / 2); page.setPivotY(height / 2); //設置縮放比例(0.0,1.0] page.setScaleX(1 - position); page.setScaleY(1 - position); } else if (position >= -1 && position < 0) {//left scrolling } else {//center } } }
我們還可以看看transformPage是怎麼來的
//這是viewpager源代碼的一部分,transformPage方法的來源 if (mPageTransformer != null) { final int scrollX = getScrollX(); final int childCount = getChildCount(); //遍歷viewpager所有的子view for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.isDecor) continue; //position等於該view的左起點減去在X軸的位移除以viewpager的寬度,也就是算出真正的位移比例 final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth(); mPageTransformer.transformPage(child, transformPos); } }
public class SimplePageTransform implements ViewPager.PageTransformer { @Override public void transformPage(View view, float position) { int width = view.getWidth(); int pivotX = 0; if (position <= 1 && position > 0) {// right scrolling pivotX = 0; } else if (position == 0) { } else if (position < 0 && position >= -1) {// left scrolling pivotX = width; } //設置x軸的錨點 view.setPivotX(pivotX); //設置繞Y軸旋轉的角度 view.setRotationY(90f * position); } }
@Override public void transformPage(View view, float position) { if (position <= 1 && position > 0) { int hashCode = view.hashCode(); Log.d(TAG,"right hashCode="+hashCode); } else if (position == 0) { int hashCode = view.hashCode(); Log.d(TAG,"center hashCode="+hashCode); } else if (position < 0 && position >= -1) { int hashCode = view.hashCode(); Log.w(TAG,"left hashCode="+hashCode); } }
看看log信息
下一頁的view hashcode
left hashCode=75472620
right hashCode=55231157
center hashCode=55231157
再下一頁的view hashcode
left hashCode=55231157
right hashCode=45932420
center hashCode=45932420
上一頁的view hashcode
left hashCode=55231157
right hashCode=45932420
center hashCode=55231157
再上一頁的view hashcode
left hashCode=75472620
right hashCode=55231157
center hashCode=75472620
由此以及上面transformPage方法的出處可得出規律,transformPage返回的view並不是一個,而是根據相應的position的返回相應的view。
也由此可以提出viewpager的坐標系(ps:不會畫圖請不要打我)
淺藍色為left view,紅色為center view,深藍色為right view,當滑動事件開始,他們的關系也會跟變化,所以可得出在[-1,0)這個區間為left,(0,1]這個區間為right,只有當等於0才為center。如果viewpager裡面view很多肯定就還會有-2,+2等等的其他坐標點,但是我們只關注left,center,right這3個view上就可以實現很多炫酷的動畫啦!
概述關於Retrofit,Rxjava,MVP等的使用現在已經成為了Android項目開發的標配,而Clean架構都能很好的兼顧這些方面,使得代碼結構清晰,而且在一般在項
作為 C/C++ 程序員,有時候我們希望在安卓上運行從 C/C++ 生成的可執行程序,而不是在 Java 中通過 jni 的方式來調用 C
1、volley項目地址 https://github.com/smanikandan14/Volley-demo(1) JSON,圖像等的異步下載;(2) 網絡請求的排
一、問題現象1、多次進出需要強制橫屏的app,比如Real FootBall2015,在退出app的時候會有概率出現退出卡頓,然後TP無法輸入的問題。2、出問題時Powe