之前在网上看到一篇viewpager简单使用的例子程序,主要采用了上部标签button+中间指示作用的imageview+下部viewpager的结构,点击上部标签,或者滑动viewpager,均可以使中间的imageview产生滑动效果,但是由于程序不够完善,当改变imageview背景等时,不能够正确的显示我们期望的UI效果,因此我对此进行了优化,同时去掉原示例中使用的animation,转而采用valueanimator+imageview的matrix方法进行编码,解决了之前UI中体现的BUG,当然远远不能说满意,权当是对viewpager、valueanimator理解的入门示例。
注:以下编码对网上的示例程序多有借鉴,但是出处找不到了
1 package com.example.testandroidviewpager; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.animation.ValueAnimator; 7 import android.app.Activity; 8 import android.graphics.BitmapFactory; 9 import android.graphics.Matrix; 10 import android.os.Bundle; 11 import android.os.Parcelable; 12 import android.support.v4.view.PagerAdapter; 13 import android.support.v4.view.ViewPager; 14 import android.support.v4.view.ViewPager.OnPageChangeListener; 15 import android.util.DisplayMetrics; 16 import android.util.Log; 17 import android.view.LayoutInflater; 18 import android.view.View; 19 import android.view.animation.AccelerateInterpolator; 20 import android.view.animation.Animation; 21 import android.view.animation.BounceInterpolator; 22 import android.view.animation.TranslateAnimation; 23 import android.widget.ImageView; 24 import android.widget.TextView; 25 26 public class MainActivity extends Activity { 27 28 private ViewPager mPager;//页卡内容 29 private List<View> listViews; // Tab页面列表 30 private ImageView cursor;// 动画图片 31 private TextView t1, t2, t3;// 页卡头标 32 private int offset = 0;// 动画图片偏移量 33 private int currIndex = 0;// 当前页卡编号 34 private int prevIndex = 0;// 移动前页卡编号 35 private int bmpW;// 动画图片宽度 36 private int screenW;//屏幕宽度,由于只是示例因此简单起见,直接使用屏幕宽度 37 @Override 38 protected void onCreate(Bundle savedInstanceState) { 39 super.onCreate(savedInstanceState); 40 setContentView(R.layout.activity_main); 41 InitTextView(); 42 InitImageView(); 43 InitViewPager(); 44 } 45 46 /** 47 * 初始化头标 48 */ 49 private void InitTextView() { 50 t1 = (TextView) findViewById(R.id.text1); 51 t2 = (TextView) findViewById(R.id.text2); 52 t3 = (TextView) findViewById(R.id.text3); 53 54 t1.setOnClickListener(new MyOnClickListener(0)); 55 t2.setOnClickListener(new MyOnClickListener(1)); 56 t3.setOnClickListener(new MyOnClickListener(2)); 57 } 58 59 /** 60 * 头标点击监听 61 */ 62 public class MyOnClickListener implements View.OnClickListener { 63 private int index = 0; 64 65 public MyOnClickListener(int i) { 66 index = i; 67 } 68 69 @Override 70 public void onClick(View v) { 71 mPager.setCurrentItem(index); 72 } 73 }; 74 75 /** 76 * 初始化ViewPager 77 */ 78 private void InitViewPager() { 79 mPager = (ViewPager) findViewById(R.id.vPager); 80 listViews = new ArrayList<View>(); 81 LayoutInflater mInflater = getLayoutInflater(); 82 listViews.add(mInflater.inflate(R.layout.page0, null)); 83 listViews.add(mInflater.inflate(R.layout.page1, null)); 84 listViews.add(mInflater.inflate(R.layout.page2, null)); 85 mPager.setAdapter(new MyPagerAdapter(listViews)); 86 mPager.setCurrentItem(0); 87 mPager.setOnPageChangeListener(new MyOnPageChangeListener()); 88 } 89 90 /** 91 * ViewPager适配器 92 */ 93 public class MyPagerAdapter extends PagerAdapter { 94 public List<View> mListViews; 95 96 public MyPagerAdapter(List<View> mListViews) { 97 this.mListViews = mListViews; 98 } 99 100 @Override 101 public void destroyItem(View arg0, int arg1, Object arg2) { 102 ((ViewPager) arg0).removeView(mListViews.get(arg1)); 103 } 104 105 @Override 106 public void finishUpdate(View arg0) { 107 } 108 109 @Override 110 public int getCount() { 111 return mListViews.size(); 112 } 113 114 @Override 115 public Object instantiateItem(View arg0, int arg1) { 116 ((ViewPager) arg0).addView(mListViews.get(arg1), 0); 117 return mListViews.get(arg1); 118 } 119 120 @Override 121 public boolean isViewFromObject(View arg0, Object arg1) { 122 Log.d("1202","view pager isViewFromObject --> return " + (arg0 == arg1)); 123 return arg0 == arg1; 124 } 125 126 @Override 127 public void restoreState(Parcelable arg0, ClassLoader arg1) { 128 } 129 130 @Override 131 public Parcelable saveState() { 132 return null; 133 } 134 135 @Override 136 public void startUpdate(View arg0) { 137 } 138 } 139 140 /** 141 * 初始化动画 142 */ 143 private void InitImageView() { 144 cursor = (ImageView) findViewById(R.id.cursor); 145 bmpW = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher) 146 .getWidth();// 获取图片宽度 147 DisplayMetrics dm = new DisplayMetrics(); 148 getWindowManager().getDefaultDisplay().getMetrics(dm); 149 screenW = dm.widthPixels;// 获取分辨率宽度 150 offset = (screenW / 3 - bmpW) / 2;// 计算偏移量 151 Matrix matrix = new Matrix(); 152 matrix.postTranslate(offset, 0); 153 cursor.setImageMatrix(matrix);// 设置动画初始位置 154 } 155 156 157 /** 158 * 页卡切换监听 159 */ 160 public class MyOnPageChangeListener implements OnPageChangeListener { 161 162 int one = screenW / 3;// 页卡1 -> 页卡2 偏移量//==screenw/3 163 int two = one * 2;// 页卡1 -> 页卡3 偏移量 164 165 @Override 166 public void onPageSelected(int arg0) { 167 168 Animation animation = null; 169 switch (arg0) { 170 case 0: 171 if (currIndex == 1) { 172 animation = new TranslateAnimation(one, 0, 0, 0); 173 } else if (currIndex == 2) { 174 animation = new TranslateAnimation(two, 0, 0, 0); 175 } 176 break; 177 case 1: 178 if (currIndex == 0) { 179 animation = new TranslateAnimation(0, one, 0, 0); 180 } else if (currIndex == 2) { 181 animation = new TranslateAnimation(two, one, 0, 0); 182 } 183 break; 184 case 2: 185 if (currIndex == 0) { 186 animation = new TranslateAnimation(0, two, 0, 0); 187 } else if (currIndex == 1) { 188 animation = new TranslateAnimation(one, two, 0, 0); 189 } 190 break; 191 } 192 final Matrix matrix = new Matrix(); 193 prevIndex = currIndex; 194 currIndex = arg0; 195 196 ValueAnimator animator0 = ValueAnimator.ofFloat(0f, 1f); 197 animator0.setDuration(300); 198 // animator0.setInterpolator(new BounceInterpolator()); 199 animator0.setInterpolator(new AccelerateInterpolator(2)); 200 animator0.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 201 202 @Override 203 public void onAnimationUpdate(ValueAnimator animation) { 204 Object o = animation.getAnimatedValue(); 205 if(o != null){ 206 float f = (Float)o; 207 Log.d("1201", "onAnimationUpdate f is " + f); 208 //prevIndex --> currIndex 209 matrix.reset(); 210 int prevX = offset + one * prevIndex; 211 int currX = offset + one * currIndex; 212 int nowValue = (int) (prevX + f * (currX - prevX)); 213 matrix.postTranslate(nowValue, 0); 214 cursor.setImageMatrix(matrix); 215 } 216 } 217 }); 218 animator0.start(); 219 220 cursor.setImageMatrix(matrix);// 设置动画初始位置 221 222 // animation.setFillAfter(true);// True:图片停在动画结束位置 223 // animation.setDuration(300); 224 // cursor.startAnimation(animation); 225 } 226 227 @Override 228 public void onPageScrolled(int arg0, float arg1, int arg2) { 229 } 230 231 @Override 232 public void onPageScrollStateChanged(int arg0) { 233 } 234 } 235 236 }
layout:activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:umadsdk="http://schemas.android.com/apk/res/com.LoveBus" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:orientation="vertical" > 7 8 <LinearLayout 9 android:id="@+id/linearLayout1" 10 android:layout_width="fill_parent" 11 android:layout_height="100.0dip" 12 android:background="#FFFFFF" > 13 14 <TextView 15 android:id="@+id/text1" 16 android:layout_width="fill_parent" 17 android:layout_height="fill_parent" 18 android:layout_weight="1.0" 19 android:gravity="center" 20 android:text="页卡1" 21 android:textColor="#000000" 22 android:textSize="22.0dip" /> 23 24 <TextView 25 android:id="@+id/text2" 26 android:layout_width="fill_parent" 27 android:layout_height="fill_parent" 28 android:layout_weight="1.0" 29 android:gravity="center" 30 android:text="页卡2" 31 android:textColor="#000000" 32 android:textSize="22.0dip" /> 33 34 <TextView 35 android:id="@+id/text3" 36 android:layout_width="fill_parent" 37 android:layout_height="fill_parent" 38 android:layout_weight="1.0" 39 android:gravity="center" 40 android:text="页卡3" 41 android:textColor="#000000" 42 android:textSize="22.0dip" /> 43 </LinearLayout> 44 45 <ImageView 46 android:id="@+id/cursor" 47 android:background="#333333" 48 android:layout_width="fill_parent" 49 android:layout_height="wrap_content" 50 android:scaleType="matrix" 51 android:src="@drawable/ic_launcher" /> 52 53 <android.support.v4.view.ViewPager 54 android:id="@+id/vPager" 55 android:layout_width="wrap_content" 56 android:layout_height="wrap_content" 57 android:layout_gravity="center" 58 android:layout_weight="1.0" 59 android:background="#000000" 60 android:flipInterval="30" 61 android:persistentDrawingCache="animation" /> 62 63 </LinearLayout>
page0.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="#330000" 6 android:orientation="vertical" > 7 8 </LinearLayout>
page1.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="#003300" 6 android:orientation="vertical" > 7 8 </LinearLayout>
page2.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="#000033" 6 android:orientation="vertical" > 7 8 </LinearLayout>
注意:位于界面中间的imageview,其scaletype一定要设置成为matrix。
原理:主要是使用valueanimator对matrix的
postTranslate()函数的参数进行了设置,然后不断更新imageview,使其具有动画效果。