我整天都在搜索关于这个问题的答案,但是找不到满意的答案。
我有一个可滚动的GridView,它包含Tile对象(下面的代码)。当应用程序作为单个JSON对象启动时,将下载所有Tile对象的图像。然后我将JSON解析为Bitmap对象,并使用setImageBitmap函数显示每个图像。
我的问题是GridView滚动性能不好,但只是在一个tile转换中(这意味着,当Adapter正在回收一个Tile对象时)。它不会多次将findViewById调用到TextViews和ImageViews,而且我目前正在使用AsyncTask和ViewHolder来避免滚动性能不佳,但没有成功。
我的问题是:当ImageView在GridView中时,使用setImageView方法的最佳做法是什么?如何避免滚动性能不佳?代码如下:
布局中的GridView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Grid that contains all event tiles -->
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:numColumns="auto_fit"
android:columnWidth="250dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:overScrollMode="never"/>
</RelativeLayout>
平铺布局
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="@+id/grid_item_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:focusable="false"
android:focusableInTouchMode="false"/>
<com.custom.CustomTextView
app:textStyle="bold"
android:id="@+id/grid_item_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:gravity="center"/>
<CheckBox
android:id="@+id/grid_item_checkbox"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:focusable="false"
android:focusableInTouchMode="false"/>
<LinearLayout
android:id="@+id/light_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"/>
</RelativeLayout>
GridView适配器
public class GridViewAdapter extends BaseAdapter {
...
public View getView(int position, View convertView, ViewGroup parent) {
TileView tileView;
// Chooses if creates new TileView or uses existing one
if (convertView == null) {
tileView = new TileView(context, parentFragment);
} else {
tileView = (TileView) convertView;
}
// Refreshes TileView with image and label at desired position.
tileView.refresh
(Images.getImage(position),
Labels.getLabel(position));
return tileView;
}
}
TileView类
public class TileView extends RelativeLayout{
private TextView textView;
private ImageView imageView;
private CheckBox checkBox;
public TileViewHolder holder;
private SetEventTask setEventTask;
/* CONSTRUCTORS */
private void init() {
LayoutInflater inflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.event_tile, this, true);
textView = (TextView) this.findViewById(R.id.grid_item_label);
imageView = (ImageView) this.findViewById(R.id.grid_item_image);
checkBox = (CheckBox) this.findViewById(R.id.grid_item_checkbox);
holder = new TileViewHolder();
holder.checkBox = checkBox;
holder.imageView = imageView;
holder.textView = textView;
this.setTag(holder);
}
/**
* Method that replaces image and label in TileView
*/
public void refresh(Bitmap image,String text){
if(setEventTask != null && !setEventTask.isCancelled()){
setEventTask.cancel(true);
}
setEventTask = new SetEventTask(image,text,holder);
setEventTask.execute();
}
public static class TileViewHolder{
public TextView textView;
public ImageView imageView;
public CheckBox checkBox;
}
}
SetImageTask AsyncTask
public class SetEventTask extends AsyncTask<Void, Void, Void>{
private final Bitmap image;
private final String text;
private final TileViewHolder holder;
public SetEventTask(Bitmap image, String text, EventTileViewHolder holder){
this.image = image;
this.text = text;
this.holder = holder;
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Void param){
holder.imageView.setImageBitmap(image);
holder.textView.setText(text);
}
}
图片类
public class Images{
public static List<Bitmap> images = new ArrayList<Bitmap>();
public static Bitmap getImage(int position){
return images.get(position)
}
public static void addImage(Bitmap image){ // image is decoded in the start of app
images.add(image);
}
}
正如你所看到的,我使用Asynctask(即使知道它没有效果,因为onPostExecute将调用UI主线程)和ViewHolder。
答案 0 :(得分:0)
好吧,我希望它有所帮助......
我没有在这里发布Manifest文件。由于动画,HardwareAcceleration是假的。我将它设置为true,我的GridView现在滚动顺畅!