2013-08-19 56 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 –

相关问题