带有ImageViews的ViewPager:页面不能平滑滑动

时间:2014-09-08 11:28:35

标签: android android-viewpager

我有一个演示活动,基本上是5个图像的集合。我将这些保存在我的/drawable目录中。我正在使用FragmentPagerAdapter的自定义实现,因为我有一组静态的片段来翻阅:

private class MyPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int pos) {
        return SDemoFragment.newInstance(pos);
    }

    @Override
    public int getCount() {
        return 5;
    }
}

我也有Fragment的自定义实现。目前,我有一个我膨胀的ImageView布局,并且根据mNum,图像源被设置为我的一个图像drawable。

public class SDemoFragment extends Fragment {
    int mNum = 0;

    /**
     * Create a new instance of CountingFragment, providing "num" as an
     * argument.
     */
    public static SDemoFragment newInstance(int num) {
        SDemoFragment f = new SDemoFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }

    /**
     * When creating, retrieve this instance's number from its arguments.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null)
            mNum = getArguments().getInt("num");
    }

    /**
     * The Fragment is created here.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.pager_item_fragment, container,
                false);
        ImageView x = (ImageView) v.findViewById(R.id.pagerItemImage);

        switch (mNum) {
        case 0:
            x.setImageResource(R.drawable.demo0);
            break;
        case 1:
            x.setImageResource(R.drawable.demo1);
            break;
        case 2:
            x.setImageResource(R.drawable.demo2);
            break;
        case 3:
            x.setImageResource(R.drawable.demo3);
            break;
        case 4:
            x.setImageResource(R.drawable.demo4);
            break;
        }
        return x;

    }
}

简单图像布局的代码: pager_item_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pagerItemImage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="Tutorial"
    android:src="@drawable/demo0" />

有没有任何理由为什么每次从一张图片滑到另一张图片时,它都会滞后?是否存在内存问题,或使用正确的方法,或每次调用inflater.inflate(...);时调用onCreateView()?任何帮助将不胜感激,如果您需要我的代码的更多部分,请不要犹豫。谢谢!

更新:我现在经常获得OutOfMemoryException

2 个答案:

答案 0 :(得分:1)

您可以使用ViewHolder模式最小化视图查找。将图像解码卸载到AsyncTask也会有很大帮助:

public View getView(int position, View v, ViewGroup parent) {
    // Need to do this only once per each view.
    ViewHolder viewHolder = new ViewHolder();
    holder.mView = v.findViewById(R.id.pagerItemImage);
    holder.mPosition = position;

    new GetImageTask(position, holder).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
    return v;
}

private static class GetImageTask extends AsyncTask {

    private int mPosition;
    private ViewHolder mHolder;

    public GetImageTask(int pos, ViewHolder holder) {
        mPosition = pos;
        mHolder = holder;
    }

    @Override
    protected Bitmap doInBackground(Void... arg0) {
        return BitmapFactory.decodeResource(getResources(), R.drawable.image);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        // Update the appropriate slide
        if (mHolder.position == mPosition) {
            // To be reconsidered. You can either set the returned image at runtime, and set it 
            // for your view, or you can store it inside the ViewHolder.
            mHolder.view.setImageBitmap(bitmap);
        }
    }
}


// This will hold all the data for you views.
private static class ViewHolder {
    private Bitmap mBitmap;
    private int    mPosition; 
    private View   mView;
}

请注意,这将存储位图。很可能你会在某些时候获得OutOfMemory。 需要更加体面的方法来解决这个问题。例如,您应该只存储当前视图,并将其邻居存储在某个偏移处。

这些伪代码可能有点不容易,但应该足以显示一般的想法。有关ViewHolders的详细信息,请参阅Smooth Scrollin - Android Developer,因为视图寻呼机/翻板将与列表视图几乎相同。

答案 1 :(得分:1)

感谢@ 2Dee关于位图加载的Android开发人员指南的链接,我意识到了我的错误:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

我将所有位图的加载移动到父Activity,并将它们加载到AsyncTask中。