2013-08-19 53 views
0

我已經設置了一個viewPager,它應該顯示大約50張圖像,分辨率爲1500,2100px。圖像由用戶自己提供。所以,我需要縮減我與這段代碼在圖片:調整圖像大小以適應ViewPager,outOfMemory異常

WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 
    Display display = wm.getDefaultDisplay(); 
    Point size = new Point(); 
    display.getSize(size); 
    int width = size.x; 
    int height = size.y; 
    //imageFile is a string to the image location. 
    Bitmap bm = BitmapFactory.decodeFile(imagefile); 
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bm, width, height, true); 

當圖像被縮小的我把它添加到viewpager其中只有少數的圖片,完美工作的數組列表。但現在我需要加載50張圖片,我該怎麼做?即使在縮小圖像後,我仍然會看到內存錯誤。

的圖像添加使用此代碼(在ViewPager):

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    ImageView imageView = new ImageView(context); 
    //int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_medium); 
    //imageView.setPadding(padding, padding, padding, padding); 
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
    //imageView.setImageResource(pages.get(position)); 
    imageView.setImageBitmap(pages.get(position)); 
    ((ViewPager) container).addView(imageView, 0); 
    return imageView; 
} 

我希望能得到一個很好的建議。我在考慮自己只加載一些圖像並動態地添加它們,但我不知道如何在我不再需要它們時銷燬加載的圖像。 我願意接受任何建議!

回答

2

嘗試使用片段和FragmentPagerAdapter在ViewPager。在這種方法中,在任何給定的時間點,ViewPager堆棧中只有3個片段(頁面)被存儲。

  1. 上一頁
  2. 當前頁
  3. 下一頁

例如: - 如果你是在ViewPager的第2頁的ViewPager棧包含第一頁,第二頁第3頁和。如果從頁面2滑動到頁面3,則會將頁面4加載到堆棧並將頁面1從堆棧中刪除。

在您的應用程序中使用此功能將節省大量的內存,因爲在任何給定的時間只有3張圖像出現在內存中。

public class MainActivity extends FragmentActivity { 


SectionsPagerAdapter mSectionsPagerAdapter; 


ViewPager mViewPager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // Create the adapter that will return a fragment for each of the three 
    // primary sections of the app. 
    mSectionsPagerAdapter = new SectionsPagerAdapter(
      getSupportFragmentManager()); 

    // Set up the ViewPager with the sections adapter. 
    mViewPager = (ViewPager) findViewById(R.id.pager); 
    mViewPager.setAdapter(mSectionsPagerAdapter); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

/** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
* one of the sections/tabs/pages. 
*/ 
public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a DummySectionFragment (defined as a static inner class 
     // below) with the page number as its lone argument. 
     Fragment fragment = new DummySectionFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public int getCount() { 
     // Show 3 total pages. 
     return 3; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     Locale l = Locale.getDefault(); 
     switch (position) { 
     case 0: 
      return getString(R.string.title_section1).toUpperCase(l); 
     case 1: 
      return getString(R.string.title_section2).toUpperCase(l); 
     case 2: 
      return getString(R.string.title_section3).toUpperCase(l); 
     } 
     return null; 
    } 
} 

/** 
* A dummy fragment representing a section of the app, but that simply 
* displays dummy text. 
*/ 
public static class DummySectionFragment extends Fragment { 
    /** 
    * The fragment argument representing the section number for this 
    * fragment. 
    */ 
    public static final String ARG_SECTION_NUMBER = "section_number"; 

    public DummySectionFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main_dummy, 
       container, false); 
     TextView dummyTextView = (TextView) rootView 
       .findViewById(R.id.section_label); 
     dummyTextView.setText(Integer.toString(getArguments().getInt(
       ARG_SECTION_NUMBER))); 
     return rootView; 
    } 
} 

您將有這個代碼與您的代碼集成 -

在開發者頁面 http://developer.android.com/training/displaying-bitmaps/display-bitmap.html

這種實現的一個例子這已經很好地解釋。讓我知道如果你需要任何進一步的幫助!:)

+0

這將是一個很好的解決方案!現在要閱讀所有內容,如果我有問題,我會回到這裏。 – Marc

+0

你有沒有適用於此的適配器的例子?無法真正解決它。 – Marc

+0

如果您使用Eclipse,請單擊文件>新建> Android應用程序項目>下一步>下一步>下一步>空白活動,然後在導航類型中選擇「可滾動選項卡+刷卡」。這將生成一個應用程序與viewpager使用片段適配器。應該讓事情更容易理解。如果你遇到任何問題,請告訴我。 –

0

利用BitmapFactory.Options將縮小版圖像加載到內存中。

你可以參考這個BitmapFactory.Options

利用inSampleSize,將其值設置爲大於1

+0

好吧,但我需要什麼樣的價值呢?這取決於什麼? – Marc

+0

樣本大小是任一維中與解碼位圖中的單個像素對應的像素數。例如,inSampleSize == 4返回的圖像是原始寬度/高度的1/4,以及像素數量的1/16 –

相關問題