我正在创建自定义ListView。适配器:
public class CustomListEventsAdapter extends BaseAdapter {
private Context context;
private List<Map<String, String>> values;
public CustomListEventsAdapter(Context context, List<Map<String, String>> values) {
this.context = context;
this.values = values;
}
@Override
public int getCount() {
return values.size();
}
@Override
public Object getItem(int position) {
return values.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final CustomItemForEventsList view = new CustomItemForEventsList(context, values.get(position), (long) position);
int itemHeight;
if (parent.getWidth() > parent.getHeight()) {
itemHeight = parent.getHeight();
} else {
itemHeight = parent.getHeight() / 2;
}
view.setLayoutParams(new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
return view;
}}
ListView项目的自定义视图:
public class CustomItemForEventsList extends View {
private MainActivity context;
private Map<String,String> values;
private long id;
private Paint pMainText;
private int viewWidth;
private int viewHeight;
private boolean isLandscape;
private Bitmap backgroundBitmap;
private RectF bitmapSizes;
private RectF viewSizes;
private Matrix matrix;
public CustomItemForEventsList(final Context context, Map<String,String> values, long id) {
super(context);
this.context = (MainActivity) context;
this.values = values;
this.id = id;
pMainText = new Paint(Paint.ANTI_ALIAS_FLAG);
pMainText.setColor(Color.WHITE);
pMainText.setTextAlign(Paint.Align.LEFT);
bitmapSizes = new RectF();
viewSizes = new RectF();
matrix = new Matrix();
loadBackgroundBitmap(values.get("url"));
}
private void loadBackgroundBitmap(final String url) {
context.imageLoader.loadImage(url, new ImageSize(viewWidth, viewHeight), context.displayImageOptions, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String s, View view) {
}
@Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
// Log.d(Statics.LOG, "onLoadingFailed");
}
@Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
backgroundBitmap = bitmap;
invalidate();
}
@Override
public void onLoadingCancelled(String s, View view) {
// Log.d(Statics.LOG, "onLoadingCanceled");
loadBackgroundBitmap(url);
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec);
isLandscape = viewWidth > viewHeight;
viewSizes.set(0, 0, viewWidth, viewHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawARGB(255, 0, 0, 0);
// Drawing view's background
if (backgroundBitmap != null) {
if (!backgroundBitmap.isRecycled()) {
bitmapSizes.set(0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
matrix.setRectToRect(viewSizes, bitmapSizes, Matrix.ScaleToFit.FILL);
matrix.invert(matrix);
canvas.drawBitmap(backgroundBitmap, matrix, null);
}
}
}}
新的Android版本(在4.0,4.2,4.4上测试)一切都很完美,但在2.3.3中,ListView项目的定位和调整大小出现了问题:位图不会调整大小以查看&#39 ; onDraw中的s大小,当我们单击ListView或滚动它并释放时。
2.3.3的屏幕。这是当我们触及ListView,然后滚动,然后等待一段时间并释放(我想在所有情况下看到的行为)时发生的事情: http://s16.postimg.org/qvf26fb45/image.png
当我们点击ListView或滚动并释放时,通常会发生这种情况: http://s22.postimg.org/d7fd8quc1/image.png
为什么会发生这种情况?我们如何解决这个问题?
答案 0 :(得分:0)
好的,我发现了如何在Android 2.3.3中解决这个问题。当然,我们可以在代码中检查Android的版本并制作两个分支:旧版本和新版本。对于新版本,请使用Matrix:
if (!backgroundBitmap.isRecycled()) {
bitmapSizes.set(0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
matrix.setRectToRect(viewSizes, bitmapSizes, Matrix.ScaleToFit.CENTER);
matrix.invert(matrix);
canvas.drawBitmap(backgroundBitmap, matrix, null);
}
对于旧版本使用@pskink在评论中提出的方法。但我不希望在不同的Android版本中看到任何差异(适合旧的,新的裁剪),所以我提供另一种方式。
我们的目标 - 避免使用Rects和Matrix进行操作,这看起来非常昂贵,并且在Android 2.3.3中为我们提供了一些绘制自定义ListView项目的错误。所以我们必须手动完成所有高级操作:
public class CustomItemForEventsList extends View {
private MainActivity context;
private int viewWidth;
private int viewHeight;
private Bitmap backgroundBitmap;
private Rect bitmapSizes;
private Rect preferedBitmapSizes;
public CustomItemForEventsList(final Context context, Map<String,String> values, long id) {
super(context);
this.context = (MainActivity) context;
bitmapSizes = new Rect();
preferedBitmapSizes = new Rect();
loadBackgroundBitmap(values.get("url"));
}
private void loadBackgroundBitmap(final String url) {
context.imageLoader.loadImage(url, new ImageSize(viewWidth, viewHeight), context.displayImageOptions, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String s, View view) {
}
@Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
// Log.d(Statics.LOG, "onLoadingFailed");
}
@Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
backgroundBitmap = bitmap;
invalidate();
}
@Override
public void onLoadingCancelled(String s, View view) {
// Log.d(Statics.LOG, "onLoadingCanceled");
loadBackgroundBitmap(url);
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawARGB(255, 0, 0, 0);
// Drawing view's background
if (backgroundBitmap != null) {
if (!backgroundBitmap.isRecycled()) {
bitmapSizes.set(0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
setPreferedBitmapSizes();
canvas.drawBitmap(backgroundBitmap, bitmapSizes, preferedBitmapSizes, null);
}
}
}
private void setPreferedBitmapSizes() {
int instBmpWidth = backgroundBitmap.getWidth();
int instBmpHeight = backgroundBitmap.getHeight();
int newBmpWidth, newBmpHeight;
newBmpWidth = viewWidth; newBmpHeight = viewWidth * instBmpHeight / instBmpWidth;
if (viewHeight > newBmpHeight) {
newBmpWidth = instBmpWidth * viewHeight / instBmpHeight; newBmpHeight = viewHeight;
if (newBmpWidth == viewWidth) {
preferedBitmapSizes.set(0, 0, newBmpWidth, newBmpHeight);
} else {
preferedBitmapSizes.set(-((newBmpWidth-viewWidth)/2), 0, viewWidth + ((newBmpWidth-viewWidth)/2), newBmpHeight);
}
} else {
if (newBmpHeight == viewHeight) {
preferedBitmapSizes.set(0, 0, newBmpWidth, newBmpHeight);
} else {
preferedBitmapSizes.set(0, -((newBmpHeight-viewHeight)/2), newBmpWidth, viewHeight + ((newBmpHeight-viewHeight)/2));
}
}
}}
现在问题解决了:
http://s29.postimg.org/hbv9d0z3b/image.png
更新:我们可以使用更简单的代码(感谢pskink,这是他的解决方案):
m.reset();
float scaleX = getWidth() / (float) b.getWidth();
float scaleY = getHeight() / (float) b.getHeight();
float scale = Math.max(scaleX, scaleY);
m.postScale(scale, scale);
float dx = (getWidth() - b.getWidth() * scale) / 2;
float dy = (getHeight() - b.getHeight() * scale) / 2;
m.postTranslate(dx, dy);
canvas.drawBitmap(b, m, null);
m - Matrix,b - 我们的位图。