国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現閱讀APP平移翻頁效果

2020-01-02 07:00:24
字體:
來源:轉載
供稿:網友

自己做的一個APP需要用到翻頁閱讀,網上看過立體翻頁效果,不過bug太多了還不兼容。看了一下多看閱讀翻頁是采用平移翻頁的,于是就仿寫了一個平移翻頁的控件。效果如下:

在翻頁時頁面右邊緣繪制了陰影,效果還不錯。要實現這種平移翻頁控件并不難,只需要定義一個布局管理頁面就可以了。具體實現上有以下難點:

    1、循環翻頁,頁面的重復利用。

    2、在翻頁時過濾掉多點觸碰。

    3、采用setAdapter的方式設置頁面布局和數據。

下面就來一一解決這幾個難點。首先看循環翻頁問題,怎么樣能采用較少的頁面實現這種翻頁呢?由于屏幕上每次只能顯示一張完整的頁面,翻過去的頁面也看不到,所以可以把翻過去的頁面拿來重復利用,不必每次都new一個頁面,所以,我只用了三張頁面實現循環翻頁。要想重復利用頁面,首先要知道頁面在布局中序號和對應的層次關系,比如一個父控件的子view的序號越大就位于越上層。循環利用頁面的原理圖如下:

向右翻頁時狀態圖是這樣的,只用了0、1、2三張頁面,頁面序號為2的位于最上層,我把它隱藏在左邊,所以看到的只有頁面1,頁面0在1下面擋著也看不到,向右翻頁時,頁面2被滑到屏幕中,這時候把頁面0的內容替換成頁面2的前一頁內容,把它放到之前頁面2的位置,這時,狀態又回到了初始狀態,又可以繼續向右翻頁了!

向左翻頁時是這樣的,初始狀態還是一樣,當頁面1被往左翻過時,看到的是頁面0,這時候頁面0下面已經沒有頁面了,而頁面2已經用不到了,這時候把頁面2放到頁面0下面,這時候狀態又回到了初始狀態,就可以繼續往左翻頁了。

類似于這種循環效果的實現我一直用的解決方案都是將選中的置于最中間,比如原理圖中的頁面1,每次翻頁完成后可見的都是頁面1。在滾動選擇器PickerView中也是同樣的方案。這就解決了頁面的重復利用問題了。

解決難點2 翻頁時過濾多點觸碰這個問題在仿淘寶商品瀏覽界面中已經解決過了,就是用一個控制變量mEvents過濾掉pointer down或up后到來的第一個move事件。

解決難點3 采用adapter方式設置頁面的布局和數據。這個在Android的AdapterView里用到的,但是我沒有看它的adapter機制,太復雜了,我就搞了個簡單的adapter,如下:

PageAdapter.java:

package com.jingchen.pagerdemo;  import android.view.View;  public abstract class PageAdapter {  /**   * @return 頁面view   */  public abstract View getView();   public abstract int getCount();   /**   * 將內容添加到view中   *   * @param view   *   包含內容的view   * @param position   *   第position頁   */  public abstract void addContent(View view, int position); } 

這是一個抽象類,getView()用于返回頁面的布局,getCount()返回數據總共需要多少頁,addContent(View view, int position)這個是每翻過一頁后將會被調用來請求頁面數據的,參數view就是頁面,position是表明第幾頁。待會兒會在自定義布局中定義setAdapter方法設置設配器。
OK,難點都解決了,自定義一個布局叫ScanView繼承自RelativeLayout:

ScanView.java:

package com.jingchen.pagerdemo;  import java.util.Timer; import java.util.TimerTask;  import android.content.Context; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.widget.RelativeLayout;  /**  * @author chenjing  *  */ public class ScanView extends RelativeLayout {  public static final String TAG = "ScanView";  private boolean isInit = true;  // 滑動的時候存在兩頁可滑動,要判斷是哪一頁在滑動  private boolean isPreMoving = true, isCurrMoving = true;  // 當前是第幾頁  private int index;  private float lastX;  // 前一頁,當前頁,下一頁的左邊位置  private int prePageLeft = 0, currPageLeft = 0, nextPageLeft = 0;  // 三張頁面  private View prePage, currPage, nextPage;  // 頁面狀態  private static final int STATE_MOVE = 0;  private static final int STATE_STOP = 1;  // 滑動的頁面,只有前一頁和當前頁可滑  private static final int PRE = 2;  private static final int CURR = 3;  private int state = STATE_STOP;  // 正在滑動的頁面右邊位置,用于繪制陰影  private float right;  // 手指滑動的距離  private float moveLenght;  // 頁面寬高  private int mWidth, mHeight;  // 獲取滑動速度  private VelocityTracker vt;  // 防止抖動  private float speed_shake = 20;  // 當前滑動速度  private float speed;  private Timer timer;  private MyTimerTask mTask;  // 滑動動畫的移動速度  public static final int MOVE_SPEED = 10;  // 頁面適配器  private PageAdapter adapter;  /**  * 過濾多點觸碰的控制變量  */  private int mEvents;   public void setAdapter(ScanViewAdapter adapter)  {  removeAllViews();  this.adapter = adapter;  prePage = adapter.getView();  addView(prePage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(prePage, index - 1);   currPage = adapter.getView();  addView(currPage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(currPage, index);   nextPage = adapter.getView();  addView(nextPage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(nextPage, index + 1);   }   /**  * 向左滑。注意可以滑動的頁面只有當前頁和前一頁  *  * @param which  */  private void moveLeft(int which)  {  switch (which)  {  case PRE:  prePageLeft -= MOVE_SPEED;  if (prePageLeft < -mWidth)  prePageLeft = -mWidth;  right = mWidth + prePageLeft;  break;  case CURR:  currPageLeft -= MOVE_SPEED;  if (currPageLeft < -mWidth)  currPageLeft = -mWidth;  right = mWidth + currPageLeft;  break;  }  }   /**  * 向右滑。注意可以滑動的頁面只有當前頁和前一頁  *  * @param which  */  private void moveRight(int which)  {  switch (which)  {  case PRE:  prePageLeft += MOVE_SPEED;  if (prePageLeft > 0)  prePageLeft = 0;  right = mWidth + prePageLeft;  break;  case CURR:  currPageLeft += MOVE_SPEED;  if (currPageLeft > 0)  currPageLeft = 0;  right = mWidth + currPageLeft;  break;  }  }   /**  * 當往回翻過一頁時添加前一頁在最左邊  */  private void addPrePage()  {  removeView(nextPage);  addView(nextPage, -1, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  // 從適配器獲取前一頁內容  adapter.addContent(nextPage, index - 1);  // 交換順序  View temp = nextPage;  nextPage = currPage;  currPage = prePage;  prePage = temp;  prePageLeft = -mWidth;  }   /**  * 當往前翻過一頁時,添加一頁在最底下  */  private void addNextPage()  {  removeView(prePage);  addView(prePage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  // 從適配器獲取后一頁內容  adapter.addContent(prePage, index + 1);  // 交換順序  View temp = currPage;  currPage = nextPage;  nextPage = prePage;  prePage = temp;  currPageLeft = 0;  }   Handler updateHandler = new Handler()  {   @Override  public void handleMessage(Message msg)  {  if (state != STATE_MOVE)  return;  // 移動頁面  // 翻回,先判斷當前哪一頁處于未返回狀態  if (prePageLeft > -mWidth && speed <= 0)  {  // 前一頁處于未返回狀態  moveLeft(PRE);  } else if (currPageLeft < 0 && speed >= 0)  {  // 當前頁處于未返回狀態  moveRight(CURR);  } else if (speed < 0 && index < adapter.getCount())  {  // 向左翻,翻動的是當前頁  moveLeft(CURR);  if (currPageLeft == (-mWidth))  {   index++;   // 翻過一頁,在底下添加一頁,把最上層頁面移除   addNextPage();  }  } else if (speed > 0 && index > 1)  {  // 向右翻,翻動的是前一頁  moveRight(PRE);  if (prePageLeft == 0)  {   index--;   // 翻回一頁,添加一頁在最上層,隱藏在最左邊   addPrePage();  }  }  if (right == 0 || right == mWidth)  {  releaseMoving();  state = STATE_STOP;  quitMove();  }  ScanView.this.requestLayout();  }   };   public ScanView(Context context, AttributeSet attrs, int defStyle)  {  super(context, attrs, defStyle);  init();  }   public ScanView(Context context)  {  super(context);  init();  }   public ScanView(Context context, AttributeSet attrs)  {  super(context, attrs);  init();  }   /**  * 退出動畫翻頁  */  public void quitMove()  {  if (mTask != null)  {  mTask.cancel();  mTask = null;  }  }   private void init()  {  index = 1;  timer = new Timer();  mTask = new MyTimerTask(updateHandler);  }   /**  * 釋放動作,不限制手滑動方向  */  private void releaseMoving()  {  isPreMoving = true;  isCurrMoving = true;  }   @Override  public boolean dispatchTouchEvent(MotionEvent event)  {  if (adapter != null)  switch (event.getActionMasked())  {  case MotionEvent.ACTION_DOWN:  lastX = event.getX();  try  {   if (vt == null)   {   vt = VelocityTracker.obtain();   } else   {   vt.clear();   }  } catch (Exception e)  {   e.printStackTrace();  }  vt.addMovement(event);  mEvents = 0;  break;  case MotionEvent.ACTION_POINTER_DOWN:  case MotionEvent.ACTION_POINTER_UP:  mEvents = -1;  break;  case MotionEvent.ACTION_MOVE:  // 取消動畫  quitMove();  Log.d("index", "mEvents = " + mEvents + ", isPreMoving = "   + isPreMoving + ", isCurrMoving = " + isCurrMoving);  vt.addMovement(event);  vt.computeCurrentVelocity(500);  speed = vt.getXVelocity();  moveLenght = event.getX() - lastX;  if ((moveLenght > 0 || !isCurrMoving) && isPreMoving   && mEvents == 0)  {   isPreMoving = true;   isCurrMoving = false;   if (index == 1)   {   // 第一頁不能再往右翻,跳轉到前一個activity   state = STATE_MOVE;   releaseMoving();   } else   {   // 非第一頁   prePageLeft += (int) moveLenght;   // 防止滑過邊界   if (prePageLeft > 0)   prePageLeft = 0;   else if (prePageLeft < -mWidth)   {   // 邊界判斷,釋放動作,防止來回滑動導致滑動前一頁時當前頁無法滑動   prePageLeft = -mWidth;   releaseMoving();   }   right = mWidth + prePageLeft;   state = STATE_MOVE;   }  } else if ((moveLenght < 0 || !isPreMoving) && isCurrMoving   && mEvents == 0)  {   isPreMoving = false;   isCurrMoving = true;   if (index == adapter.getCount())   {   // 最后一頁不能再往左翻   state = STATE_STOP;   releaseMoving();   } else   {   currPageLeft += (int) moveLenght;   // 防止滑過邊界   if (currPageLeft < -mWidth)   currPageLeft = -mWidth;   else if (currPageLeft > 0)   {   // 邊界判斷,釋放動作,防止來回滑動導致滑動當前頁是前一頁無法滑動   currPageLeft = 0;   releaseMoving();   }   right = mWidth + currPageLeft;   state = STATE_MOVE;   }   } else   mEvents = 0;  lastX = event.getX();  requestLayout();  break;  case MotionEvent.ACTION_UP:  if (Math.abs(speed) < speed_shake)   speed = 0;  quitMove();  mTask = new MyTimerTask(updateHandler);  timer.schedule(mTask, 0, 5);  try  {   vt.clear();   vt.recycle();  } catch (Exception e)  {   e.printStackTrace();  }  break;  default:  break;  }  super.dispatchTouchEvent(event);  return true;  }   /*  * (非 Javadoc) 在這里繪制翻頁陰影效果  *  * @see android.view.ViewGroup#dispatchDraw(android.graphics.Canvas)  */  @Override  protected void dispatchDraw(Canvas canvas)  {  super.dispatchDraw(canvas);  if (right == 0 || right == mWidth)  return;  RectF rectF = new RectF(right, 0, mWidth, mHeight);  Paint paint = new Paint();  paint.setAntiAlias(true);  LinearGradient linearGradient = new LinearGradient(right, 0,  right + 36, 0, 0xffbbbbbb, 0x00bbbbbb, TileMode.CLAMP);  paint.setShader(linearGradient);  paint.setStyle(Style.FILL);  canvas.drawRect(rectF, paint);  }   @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  mWidth = getMeasuredWidth();  mHeight = getMeasuredHeight();  if (isInit)  {  // 初始狀態,一頁放在左邊隱藏起來,兩頁疊在一塊  prePageLeft = -mWidth;  currPageLeft = 0;  nextPageLeft = 0;  isInit = false;  }  }   @Override  protected void onLayout(boolean changed, int l, int t, int r, int b)  {  if (adapter == null)  return;  prePage.layout(prePageLeft, 0,  prePageLeft + prePage.getMeasuredWidth(),  prePage.getMeasuredHeight());  currPage.layout(currPageLeft, 0,  currPageLeft + currPage.getMeasuredWidth(),  currPage.getMeasuredHeight());  nextPage.layout(nextPageLeft, 0,  nextPageLeft + nextPage.getMeasuredWidth(),  nextPage.getMeasuredHeight());  invalidate();  }   class MyTimerTask extends TimerTask  {  Handler handler;   public MyTimerTask(Handler handler)  {  this.handler = handler;  }   @Override  public void run()  {  handler.sendMessage(handler.obtainMessage());  }   } } 

代碼中的注釋寫的非常多,原理理解了看代碼就容易看懂了。寫完這個布局后再寫一個ScanViewAdapter繼承PageAdapter:

package com.jingchen.pagerdemo;  import java.util.Timer; import java.util.TimerTask;  import android.content.Context; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.widget.RelativeLayout;  /**  * @author chenjing  *  */ public class ScanView extends RelativeLayout {  public static final String TAG = "ScanView";  private boolean isInit = true;  // 滑動的時候存在兩頁可滑動,要判斷是哪一頁在滑動  private boolean isPreMoving = true, isCurrMoving = true;  // 當前是第幾頁  private int index;  private float lastX;  // 前一頁,當前頁,下一頁的左邊位置  private int prePageLeft = 0, currPageLeft = 0, nextPageLeft = 0;  // 三張頁面  private View prePage, currPage, nextPage;  // 頁面狀態  private static final int STATE_MOVE = 0;  private static final int STATE_STOP = 1;  // 滑動的頁面,只有前一頁和當前頁可滑  private static final int PRE = 2;  private static final int CURR = 3;  private int state = STATE_STOP;  // 正在滑動的頁面右邊位置,用于繪制陰影  private float right;  // 手指滑動的距離  private float moveLenght;  // 頁面寬高  private int mWidth, mHeight;  // 獲取滑動速度  private VelocityTracker vt;  // 防止抖動  private float speed_shake = 20;  // 當前滑動速度  private float speed;  private Timer timer;  private MyTimerTask mTask;  // 滑動動畫的移動速度  public static final int MOVE_SPEED = 10;  // 頁面適配器  private PageAdapter adapter;  /**  * 過濾多點觸碰的控制變量  */  private int mEvents;   public void setAdapter(ScanViewAdapter adapter)  {  removeAllViews();  this.adapter = adapter;  prePage = adapter.getView();  addView(prePage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(prePage, index - 1);   currPage = adapter.getView();  addView(currPage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(currPage, index);   nextPage = adapter.getView();  addView(nextPage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  adapter.addContent(nextPage, index + 1);   }   /**  * 向左滑。注意可以滑動的頁面只有當前頁和前一頁  *  * @param which  */  private void moveLeft(int which)  {  switch (which)  {  case PRE:  prePageLeft -= MOVE_SPEED;  if (prePageLeft < -mWidth)  prePageLeft = -mWidth;  right = mWidth + prePageLeft;  break;  case CURR:  currPageLeft -= MOVE_SPEED;  if (currPageLeft < -mWidth)  currPageLeft = -mWidth;  right = mWidth + currPageLeft;  break;  }  }   /**  * 向右滑。注意可以滑動的頁面只有當前頁和前一頁  *  * @param which  */  private void moveRight(int which)  {  switch (which)  {  case PRE:  prePageLeft += MOVE_SPEED;  if (prePageLeft > 0)  prePageLeft = 0;  right = mWidth + prePageLeft;  break;  case CURR:  currPageLeft += MOVE_SPEED;  if (currPageLeft > 0)  currPageLeft = 0;  right = mWidth + currPageLeft;  break;  }  }   /**  * 當往回翻過一頁時添加前一頁在最左邊  */  private void addPrePage()  {  removeView(nextPage);  addView(nextPage, -1, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  // 從適配器獲取前一頁內容  adapter.addContent(nextPage, index - 1);  // 交換順序  View temp = nextPage;  nextPage = currPage;  currPage = prePage;  prePage = temp;  prePageLeft = -mWidth;  }   /**  * 當往前翻過一頁時,添加一頁在最底下  */  private void addNextPage()  {  removeView(prePage);  addView(prePage, 0, new LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT));  // 從適配器獲取后一頁內容  adapter.addContent(prePage, index + 1);  // 交換順序  View temp = currPage;  currPage = nextPage;  nextPage = prePage;  prePage = temp;  currPageLeft = 0;  }   Handler updateHandler = new Handler()  {   @Override  public void handleMessage(Message msg)  {  if (state != STATE_MOVE)  return;  // 移動頁面  // 翻回,先判斷當前哪一頁處于未返回狀態  if (prePageLeft > -mWidth && speed <= 0)  {  // 前一頁處于未返回狀態  moveLeft(PRE);  } else if (currPageLeft < 0 && speed >= 0)  {  // 當前頁處于未返回狀態  moveRight(CURR);  } else if (speed < 0 && index < adapter.getCount())  {  // 向左翻,翻動的是當前頁  moveLeft(CURR);  if (currPageLeft == (-mWidth))  {   index++;   // 翻過一頁,在底下添加一頁,把最上層頁面移除   addNextPage();  }  } else if (speed > 0 && index > 1)  {  // 向右翻,翻動的是前一頁  moveRight(PRE);  if (prePageLeft == 0)  {   index--;   // 翻回一頁,添加一頁在最上層,隱藏在最左邊   addPrePage();  }  }  if (right == 0 || right == mWidth)  {  releaseMoving();  state = STATE_STOP;  quitMove();  }  ScanView.this.requestLayout();  }   };   public ScanView(Context context, AttributeSet attrs, int defStyle)  {  super(context, attrs, defStyle);  init();  }   public ScanView(Context context)  {  super(context);  init();  }   public ScanView(Context context, AttributeSet attrs)  {  super(context, attrs);  init();  }   /**  * 退出動畫翻頁  */  public void quitMove()  {  if (mTask != null)  {  mTask.cancel();  mTask = null;  }  }   private void init()  {  index = 1;  timer = new Timer();  mTask = new MyTimerTask(updateHandler);  }   /**  * 釋放動作,不限制手滑動方向  */  private void releaseMoving()  {  isPreMoving = true;  isCurrMoving = true;  }   @Override  public boolean dispatchTouchEvent(MotionEvent event)  {  if (adapter != null)  switch (event.getActionMasked())  {  case MotionEvent.ACTION_DOWN:  lastX = event.getX();  try  {   if (vt == null)   {   vt = VelocityTracker.obtain();   } else   {   vt.clear();   }  } catch (Exception e)  {   e.printStackTrace();  }  vt.addMovement(event);  mEvents = 0;  break;  case MotionEvent.ACTION_POINTER_DOWN:  case MotionEvent.ACTION_POINTER_UP:  mEvents = -1;  break;  case MotionEvent.ACTION_MOVE:  // 取消動畫  quitMove();  Log.d("index", "mEvents = " + mEvents + ", isPreMoving = "   + isPreMoving + ", isCurrMoving = " + isCurrMoving);  vt.addMovement(event);  vt.computeCurrentVelocity(500);  speed = vt.getXVelocity();  moveLenght = event.getX() - lastX;  if ((moveLenght > 0 || !isCurrMoving) && isPreMoving   && mEvents == 0)  {   isPreMoving = true;   isCurrMoving = false;   if (index == 1)   {   // 第一頁不能再往右翻,跳轉到前一個activity   state = STATE_MOVE;   releaseMoving();   } else   {   // 非第一頁   prePageLeft += (int) moveLenght;   // 防止滑過邊界   if (prePageLeft > 0)   prePageLeft = 0;   else if (prePageLeft < -mWidth)   {   // 邊界判斷,釋放動作,防止來回滑動導致滑動前一頁時當前頁無法滑動   prePageLeft = -mWidth;   releaseMoving();   }   right = mWidth + prePageLeft;   state = STATE_MOVE;   }  } else if ((moveLenght < 0 || !isPreMoving) && isCurrMoving   && mEvents == 0)  {   isPreMoving = false;   isCurrMoving = true;   if (index == adapter.getCount())   {   // 最后一頁不能再往左翻   state = STATE_STOP;   releaseMoving();   } else   {   currPageLeft += (int) moveLenght;   // 防止滑過邊界   if (currPageLeft < -mWidth)   currPageLeft = -mWidth;   else if (currPageLeft > 0)   {   // 邊界判斷,釋放動作,防止來回滑動導致滑動當前頁是前一頁無法滑動   currPageLeft = 0;   releaseMoving();   }   right = mWidth + currPageLeft;   state = STATE_MOVE;   }   } else   mEvents = 0;  lastX = event.getX();  requestLayout();  break;  case MotionEvent.ACTION_UP:  if (Math.abs(speed) < speed_shake)   speed = 0;  quitMove();  mTask = new MyTimerTask(updateHandler);  timer.schedule(mTask, 0, 5);  try  {   vt.clear();   vt.recycle();  } catch (Exception e)  {   e.printStackTrace();  }  break;  default:  break;  }  super.dispatchTouchEvent(event);  return true;  }   /*  * (非 Javadoc) 在這里繪制翻頁陰影效果  *  * @see android.view.ViewGroup#dispatchDraw(android.graphics.Canvas)  */  @Override  protected void dispatchDraw(Canvas canvas)  {  super.dispatchDraw(canvas);  if (right == 0 || right == mWidth)  return;  RectF rectF = new RectF(right, 0, mWidth, mHeight);  Paint paint = new Paint();  paint.setAntiAlias(true);  LinearGradient linearGradient = new LinearGradient(right, 0,  right + 36, 0, 0xffbbbbbb, 0x00bbbbbb, TileMode.CLAMP);  paint.setShader(linearGradient);  paint.setStyle(Style.FILL);  canvas.drawRect(rectF, paint);  }   @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  mWidth = getMeasuredWidth();  mHeight = getMeasuredHeight();  if (isInit)  {  // 初始狀態,一頁放在左邊隱藏起來,兩頁疊在一塊  prePageLeft = -mWidth;  currPageLeft = 0;  nextPageLeft = 0;  isInit = false;  }  }   @Override  protected void onLayout(boolean changed, int l, int t, int r, int b)  {  if (adapter == null)  return;  prePage.layout(prePageLeft, 0,  prePageLeft + prePage.getMeasuredWidth(),  prePage.getMeasuredHeight());  currPage.layout(currPageLeft, 0,  currPageLeft + currPage.getMeasuredWidth(),  currPage.getMeasuredHeight());  nextPage.layout(nextPageLeft, 0,  nextPageLeft + nextPage.getMeasuredWidth(),  nextPage.getMeasuredHeight());  invalidate();  }   class MyTimerTask extends TimerTask  {  Handler handler;   public MyTimerTask(Handler handler)  {  this.handler = handler;  }   @Override  public void run()  {  handler.sendMessage(handler.obtainMessage());  }   } } 

這里只是我的demo里寫的Adapter,也可以寫成帶更多內容的Adapter。addContent里帶的參數view就是getView里面返回的view,這樣就可以根據inflate的布局設置內容了,getView返回的布局page_layout.xml如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/cover" >   <TextView  android:id="@+id/content"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_centerHorizontal="true"  android:layout_marginTop="60dp"  android:padding="10dp"  android:textColor="#000000"  android:textSize="22sp" />   <TextView  android:id="@+id/index"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true"  android:layout_centerHorizontal="true"  android:layout_marginBottom="60dp"  android:textColor="#000000"  android:textSize="30sp" />  </RelativeLayout> 

只包含了兩個TextView,所以在adapter中可以根據id查找到這兩個TextView再給它設置內容。
OK了,MainActivity的布局如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/cover" >   <TextView  android:id="@+id/content"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_centerHorizontal="true"  android:layout_marginTop="60dp"  android:padding="10dp"  android:textColor="#000000"  android:textSize="22sp" />   <TextView  android:id="@+id/index"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true"  android:layout_centerHorizontal="true"  android:layout_marginBottom="60dp"  android:textColor="#000000"  android:textSize="30sp" />  </RelativeLayout> 

很簡單,只包含了ScanView。
MainActivity的代碼:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="@drawable/cover" >   <TextView  android:id="@+id/content"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_centerHorizontal="true"  android:layout_marginTop="60dp"  android:padding="10dp"  android:textColor="#000000"  android:textSize="22sp" />   <TextView  android:id="@+id/index"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true"  android:layout_centerHorizontal="true"  android:layout_marginBottom="60dp"  android:textColor="#000000"  android:textSize="30sp" />  </RelativeLayout> 

給ScanView設置Adapter就可以了。
好啦,仿多看的平移翻頁就完成了。

希望本文對大家學習Android軟件編程有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凤凰县| 霞浦县| 河东区| 伊吾县| 寿宁县| 梁山县| 上饶市| 黄冈市| 通许县| 克拉玛依市| 车致| 武定县| 顺昌县| 密云县| 全椒县| 阿拉善右旗| 高州市| 龙海市| 陕西省| 株洲市| 镇雄县| 本溪市| 社旗县| 安多县| 金乡县| 洪江市| 西青区| 建湖县| 阜平县| 承德县| 旺苍县| 沁阳市| 常宁市| 麦盖提县| 林甸县| 新竹市| 长武县| 襄汾县| 和田县| 乌鲁木齐县| 长岛县|