调整图像大小以适应ViewPager,outOfMemory异常

时间:2013-08-19 11:28:29

标签: android android-viewpager out-of-memory image-scaling

我已经设置了一个viewPager,它应该显示大约50张图像,分辨率为1500,2100px。图像由用户自己提供。因此,我需要使用这段代码缩小图像的尺寸:

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);

当缩小图像时,我将它添加到arrayList中的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 个答案:

答案 0 :(得分:2)

尝试在ViewPager中使用Fragments和FragmentPagerAdapter。在此方法中,在任何给定的时间点,只有3个片段(页面)存储在ViewPager堆栈中。

  1. 上一页
  2. 当前页面
  3. 下一页
  4. Ex: - 如果您位于ViewPager的第2页,ViewPager堆栈包含Page1,Page2和Page3。如果从第2页滑到第3页,则第4页被加载到堆栈中,第1页从堆栈中删除。

    在您的应用程序中使用此功能将节省大量内存,因为在任何给定时间内存储器中只有3张图像。

    这在开发者页面中得到了很好的解释 http://developer.android.com/training/displaying-bitmaps/display-bitmap.html

    此实施的一个示例 -

    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;
        }
    }
    

    您必须将此代码与代码集成。如果您需要任何进一步的帮助,请告诉我们!:)

答案 1 :(得分:0)

利用BitmapFactory.Options将缩小版图像加载到内存中。

您可以参考此BitmapFactory.Options

使用inSampleSize,将其值设置为大于1。