GridView不是平滑的.如何优化网格视图



我创建了一个简单的图像库,显示存储在res/drawable文件夹中的图像,但是网格视图非常滞后和缓慢。我怎样才能进一步优化网格视图,使移动更顺畅。

  public class ImageGalleryActivity extends Activity {
    String strCategoryName = null;
    GridView gridView;
    Utils utils;
    private int columnWidth;
    // private GridViewImageAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_gallery);
        Intent intent;
        intent = getIntent();
        if (intent != null) {
            strCategoryName = intent.getStringExtra("category");
        }

        gridView = (GridView) findViewById(R.id.gridView_cards);
        utils = new Utils(this);
        // Intializing Grid View
        InitilizeGridLayout();
        // gridView.setAdapter(new GridCustomAdapter(this));
        // adapter = new GridViewImageAdapter(ImageGalleryActivity.this,
        // defaultImages, columnWidth, this);
        List<Item> items = new ArrayList<Item>();
        if(strCategoryName.equals("test"))
        {
            items.add(new Item(R.drawable.i1));
            items.add(new Item(R.drawable.i2));
            items.add(new Item(R.drawable.i3));
            items.add(new Item(R.drawable.i4));
            items.add(new Item(R.drawable.i5));
            items.add(new Item(R.drawable.i6));
            items.add(new Item(R.drawable.i7));
            items.add(new Item(R.drawable.i8));
            items.add(new Item(R.drawable.i9));
            items.add(new Item(R.drawable.i10));
            items.add(new Item(R.drawable.i11));
            items.add(new Item(R.drawable.i12));
            items.add(new Item(R.drawable.i13));
            items.add(new Item(R.drawable.i14));
            items.add(new Item(R.drawable.i15));
            items.add(new Item(R.drawable.i16));
            items.add(new Item(R.drawable.i17));
            items.add(new Item(R.drawable.i18));
            items.add(new Item(R.drawable.i19));
            items.add(new Item(R.drawable.i20));
            items.add(new Item(R.drawable.i21));
            items.add(new Item(R.drawable.i22));
            items.add(new Item(R.drawable.i23));
            items.add(new Item(R.drawable.i24));
            items.add(new Item(R.drawable.i25));
        }
        else if(strCategoryName.equals("test")){
            items.add(new Item(R.drawable.i1));
            items.add(new Item(R.drawable.i2));
            items.add(new Item(R.drawable.i3));
            items.add(new Item(R.drawable.i4));
            items.add(new Item(R.drawable.i5));
            items.add(new Item(R.drawable.i6));
            items.add(new Item(R.drawable.i7));
            items.add(new Item(R.drawable.i8));
            items.add(new Item(R.drawable.i9));
            items.add(new Item(R.drawable.i10));
            items.add(new Item(R.drawable.i11));
            items.add(new Item(R.drawable.i12));
            items.add(new Item(R.drawable.i13));
            items.add(new Item(R.drawable.i14));
            items.add(new Item(R.drawable.i15));
            items.add(new Item(R.drawable.i16));
            items.add(new Item(R.drawable.i17));
            items.add(new Item(R.drawable.i18));
        }else{
            items.add(new Item(R.drawable.i1));
            items.add(new Item(R.drawable.i2));
            items.add(new Item(R.drawable.i3));
            items.add(new Item(R.drawable.i4));
            items.add(new Item(R.drawable.i5));
            items.add(new Item(R.drawable.i6));
            items.add(new Item(R.drawable.i7));
            items.add(new Item(R.drawable.i8));
            items.add(new Item(R.drawable.i9));
            items.add(new Item(R.drawable.i10));
            items.add(new Item(R.drawable.i11));
            items.add(new Item(R.drawable.i12));
            items.add(new Item(R.drawable.i13));
            items.add(new Item(R.drawable.i14));
            items.add(new Item(R.drawable.i15));
            items.add(new Item(R.drawable.i16));
            items.add(new Item(R.drawable.i17));
            items.add(new Item(R.drawable.i18));
        }

        gridView.setAdapter(new MyAdapter(this, items, columnWidth, ImageGalleryActivity.this));
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.image_gallery, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    private void InitilizeGridLayout() {
        Resources r = getResources();
        float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                AppConstant.GRID_PADDING, r.getDisplayMetrics());
        columnWidth = (int) ((utils.getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);
        gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
        gridView.setColumnWidth(columnWidth);
        gridView.setStretchMode(GridView.NO_STRETCH);
        gridView.setPadding((int) padding, (int) padding, (int) padding,
                (int) padding);
        gridView.setHorizontalSpacing((int) padding);
        gridView.setVerticalSpacing((int) padding);
    }
}
class MyAdapter extends BaseAdapter {
    private List<Item> items;
    private Context context;
    int columnWidth;
    Activity _activity;
    public MyAdapter(Context context, List<Item> items, int columnWidth, Activity activity) {
        this.context = context;
        this.items = items;
        this.columnWidth = columnWidth;
        this._activity = activity;
    }
    @Override
    public int getCount() {
        return items.size();
    }
    @Override
    public Object getItem(int i) {
        return items.get(i);
    }
    @Override
    public long getItemId(int i) {
        return i;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(
                    R.layout.frame_layout_square_image_view, null, false);
            holder.picture = (ImageView) convertView.findViewById(R.id.picture);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.picture.setImageBitmap((decodeImage(
                items.get(position).drawableId, columnWidth)));
         holder.picture.setOnClickListener(new OnImageClickListener(items.get(position).drawableId));
        return convertView;
    }
    class OnImageClickListener implements OnClickListener {
        int _drawableId;
        // constructor
        public OnImageClickListener(int drawableId) {
            this._drawableId = drawableId;
        }
        @Override
        public void onClick(View v) {
            // on selecting grid view image
            // launch full screen activity
            Intent i = new Intent(_activity, ImageEditor.class);
            i.putExtra("drawableId", _drawableId);
            _activity.startActivity(i);
        }
    }
    class ViewHolder {
        ImageView picture;
    }
    public Bitmap decodeImage(int resourceId, int imageSize) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(context.getResources(), resourceId, o);
            // The new size we want to scale to
            final int REQUIRED_SIZE = imageSize; // you are free to modify size
                                                    // as your requirement
            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE
                    && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;
            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeResource(context.getResources(),
                    resourceId, o2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
}
class Item {
    final int drawableId;
    Item(int drawableId) {
        this.drawableId = drawableId;
    }
}

尝试gridView.setSmoothScrollbarEnabled(true);它将使用基于屏幕上可见项目的像素高度的更精细的计算方法。http://developer.android.com/reference/android/widget/GridView.html

首先我认为这一行:

holder.picture.setOnClickListener(new OnImageClickListener(items.get(position).drawableId));

相当重,您在每次getView调用时分配一个匿名类。如果你真的想确保你可以跟踪你的内存分配(http://developer.android.com/tools/debugging/ddms.html#alloc)。

你可以很容易地做一个监听器成员,你只分配一次:

private OnClickListener myImageClickListener = new OnImageClickListener();

然后在getView中你只需

holder.picture.setOnClickListener(myImageClickListener);

要有一个更"通用"的监听器,你可以(在你的getView):

holder.picture = (ImageView) convertView.findViewById(R.id.picture);
holder.picture.setTag(items.get(position).drawableId);

然后:

@Override
    public void onClick(View v) {
        int drawableId = Integer.valueOf(v.getTag());
}

这可能已经缓解了痛苦:)

我有一个非常不流畅的滚动体验和你一样的问题。我同意Mate Krizanac的观点——基本上你想做的是在一个不是主UI线程的线程上加载任何图像。所以你可以使用Picasso或ImageLoader类,或者使用AsyncTask将图像加载到ViewHolder中。另一种优化方法是将图像缩小一点。网上有很多代码可以帮助你做到这一点。希望这对你有所帮助。如果您需要实际代码来解释,请告诉我。

最新更新