2013-02-05 33 views
2

我伸出ViewPager有一個移動背景(似乎是一個fairly popular要求太)重寫的onDraw爲ViewPager有時會黑屏

這似乎是主要的工作,我的問題是,有時整個背景匝黑色。

實際上,當我在另一個頁面上旋轉屏幕而不是第一個屏幕時開始移動(在屏幕旋轉後它仍然可以) - 當屏幕旋轉後重新開始活動時,它將ViewPager恢復爲與之前相同的頁面。

整個代碼與應用程序在GitHub,但這裏是感興趣的類。

package com.matthieu; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.*; 
import android.os.Build; 
import android.support.v4.view.ViewPager; 
import android.util.AttributeSet; 
import android.util.Log; 

import java.io.IOException; 
import java.io.InputStream; 

public class ViewPagerParallax extends ViewPager { 
    int background_id =-1; 
    int background_saved_id =-1; 
    int saved_width=-1, saved_height=-1, saved_max_num_pages =-1; 
    Bitmap saved_bitmap; 

    int max_num_pages=0; 
    int imageHeight; 
    int imageWidth; 
    float zoom_level; 

    Rect r = new Rect(); 

    private final static String TAG="ViewPagerParallax"; 

    public ViewPagerParallax(Context context) { 
     super(context); 
    } 

    public ViewPagerParallax(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @SuppressLint({"NewApi"}) 
    private void set_new_background() { 
     if (background_id == -1) 
      return; 

     if (max_num_pages == 0) 
      return; 

     if (getWidth()==0 || getHeight()==0) 
      return; 

     if ((saved_height == getHeight()) && (saved_width == getWidth()) && 
       (background_saved_id==background_id) && 
       (saved_max_num_pages == max_num_pages)) 
      return; 

     InputStream is; 

     try { 
      is = getContext().getResources().openRawResource(background_id); 

      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(is, null, options); 

      imageHeight = options.outHeight; 
      imageWidth = options.outWidth; 

      zoom_level = ((float) imageHeight)/getHeight(); // we are always in 'fitY' mode 
      is.reset(); 

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1) { 
       BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(is, true); 

       options.inJustDecodeBounds = false; 
       r.set(0, 0, Math.min((int) (getWidth() * ((max_num_pages + 4.0)/5) * zoom_level), imageWidth), imageHeight); 
       saved_bitmap = brd.decodeRegion(r, options); 
       brd.recycle(); 
      } else { 
       saved_bitmap = Bitmap.createBitmap(BitmapFactory.decodeStream(is), 0, 0, Math.min((int) (getWidth() * ((max_num_pages + 4.0)/5) * zoom_level), imageWidth), imageHeight); 
      } 

      is.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "Cannot decode: " + e.getMessage()); 
      background_id = -1; 
      return; 
     } 

     saved_height = getHeight(); 
     saved_width = getWidth(); 
     background_saved_id = background_id; 
     saved_max_num_pages = max_num_pages; 
    } 

    int current_position; 
    float current_offset; 

    @Override 
    protected void onPageScrolled(int position, float offset, int offsetPixels) { 
     super.onPageScrolled(position, offset, offsetPixels); 
     current_position = position; 
     current_offset = offset; 
    } 

    Rect src = new Rect(), dst = new Rect(); 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     src.set((int) (((current_position + current_offset) * getWidth() * zoom_level)/5), 0, 
       (int) ((((current_position + current_offset) * getWidth() * zoom_level)/5) + (getWidth() * zoom_level)), imageHeight); 

     dst.set((int) ((current_position + current_offset) * getWidth()), 0, (int) ((current_position + current_offset) * getWidth()) + canvas.getWidth(), canvas.getHeight()); 
     // still confused why we need to shift also in the destination canvas 

     canvas.drawBitmap(saved_bitmap, src, dst, null); 
    } 

    public void set_max_pages(int num_max_pages) { 
     max_num_pages = num_max_pages; 
     set_new_background(); 
    } 

    public void setBackgroundAsset(int res_id) { 
     background_id = res_id; 
     set_new_background(); 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     super.onLayout(changed, l, t, r, b); 
     set_new_background(); 
    } 
} 

回答

0

中畫布偏移是基於在第一頁上被繪製計算...固定的代碼ØGitHub上,現在只希望這不是東西,是完全依賴於實現,後來改變...