在自定义视图列表视图项中缩放位图图像
Scaling bitmap image in custom view listview item
我在为列表视图项中的自定义视图缩放和显示我的位图图像时遇到了问题。
我使用延迟加载来显示我的图像,并且在下载和显示图像时我的自定义视图显示加载 gif。我在 this tutorial 中为 lazyload 定制了类并且它有效。我认为我的问题是将下载的位图绘制到自定义视图的 canvas 中。
我想列出我的问题和我到目前为止的代码。
- 在自定义视图中显示的图像质量下降。不知道为什么。
- 当我向下或向上滚动列表视图时,可以感觉到它没有正确滚动。
- 我的图像应该匹配父图像,高度应该按宽度的变化比例缩放。
真的,这对我来说是个大问题,我无法处理。如有任何帮助和建议,我们将不胜感激。
我的适配器中的 getView 方法
ImagePrevLoader imgLoader = new ImagePrevLoader(context); // actually it is initilized in constructor of adapter
public View getView(final int position, final View convertView, ViewGroup parent) {
ArtItemHolder holder;
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) this.context).getLayoutInflater();
holder = new ArtItemHolder();
view = inflater.inflate(R.layout.feed_list_item, parent, false);
holder.image = view.findViewById(R.id.img_Image);
holder.pubDate = (TextView) view.findViewById(R.id.txt_puslishDate);
holder.arTitle = (TextView) view.findViewById(R.id.txt_arTitle);
view.setTag(holder);
} else {
holder = (AdvItemHolder) view.getTag();
}
Article ar= articles.get(position);
imgLoader.DisplayImage(ar.getImages().get(0).getUrl(), (ImagePreView) holder.image);
return view;
}
private static class ArtItemHolder{
View image;
TextView pubDate;
TextView arTitle;
}
我的自定义视图
public class ImagePreView extends View{
private static String TAG = "ImagePreView";
private Movie gifImage;
private Bitmap myImage;
Context context;
public ImagePreView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
if (!isInEditMode()) {
new ImagePreView(context, attrs, defStyleAttr);
}
init();
}
public ImagePreView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
this.context = context;
init();
}
public ImagePreView(Context context) {
super(context, null, 0);
this.context = context;
init();
}
private void init(){
setLayerType(View.LAYER_TYPE_SOFTWARE, null);// yada manifeste android:hardwareAccelerated="false" ekle
//setFocusable(true);
InputStream is;
try {
is = context.getResources().getAssets().open("dialogbox_loader.gif");
gifImage = Movie.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDraw(Canvas canvas) {
//canvas.drawColor(0xFFD8D8D8);
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setColor(0xFFA4A4A4);
paint.setStrokeWidth( 2.4f );
paint.setStyle( Style.STROKE );
canvas.drawRect( 0, 0, getWidth(), getHeight(), paint );
super.onDraw(canvas);
if(getWidth() < 1 || getHeight()<1)
requestLayout();
//Log.d(TAG, "WIDTH : " + getWidth()+ ", HEIGHT : " + getHeight());
if(myImage != null){
int width = (getWidth() - myImage.getWidth())/2;
int height = (getHeight() - myImage.getHeight())/2;
canvas.drawBitmap(myImage, width, height, new Paint());
} else if(gifImage != null){
//canvas.drawColor(0, Mode.CLEAR);
//Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//canvas.drawBitmap(b, 0, 0, new Paint());
showLoadingGif(canvas);
}
}
long movieStart ;
private void showLoadingGif(Canvas canvas){
long now = android.os.SystemClock.uptimeMillis();
if (movieStart == 0)
movieStart = now;
int relTime = (int) ((now - movieStart) % gifImage.duration());
gifImage.setTime(relTime);
int width = getWidth()/2 - gifImage.width()/2;
int height = getHeight()/2 - gifImage.height()/2;
gifImage.draw(canvas, width, height);
this.invalidate();
}
public void display(Bitmap bitmap){
this.myImage = getScaledBitmap(bitmap);
invalidate();
}
private Bitmap getScaledBitmap(Bitmap bitmap) {
int viewWidth = getWidth();
int viewHeight = getHeight();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int boundBoxInDp = viewWidth;
if(viewHeight>viewWidth)
boundBoxInDp = viewHeight;
float xScale = ((float) boundBoxInDp) / width;
float yScale = ((float) boundBoxInDp) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
try {
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return scaledBitmap;
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
列表视图项目布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:id="@+id/feed_item_parent">
<TextView
android:id="@+id/txt_arTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@color/main_text_color"
android:textSize="15sp"
android:textStyle="bold"/>
<com.mobile.zenex.component.ImagePreView
android:id="@+id/img_Image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/txt_puslishDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@color/grey_text_color"
android:textSize="15sp"
android:textStyle="bold"/>
</LinearLayout>
尝试使用 Picasso downloading/caching,它可以提高质量/下载速度:
我在为列表视图项中的自定义视图缩放和显示我的位图图像时遇到了问题。 我使用延迟加载来显示我的图像,并且在下载和显示图像时我的自定义视图显示加载 gif。我在 this tutorial 中为 lazyload 定制了类并且它有效。我认为我的问题是将下载的位图绘制到自定义视图的 canvas 中。 我想列出我的问题和我到目前为止的代码。
- 在自定义视图中显示的图像质量下降。不知道为什么。
- 当我向下或向上滚动列表视图时,可以感觉到它没有正确滚动。
- 我的图像应该匹配父图像,高度应该按宽度的变化比例缩放。
真的,这对我来说是个大问题,我无法处理。如有任何帮助和建议,我们将不胜感激。
我的适配器中的 getView 方法
ImagePrevLoader imgLoader = new ImagePrevLoader(context); // actually it is initilized in constructor of adapter
public View getView(final int position, final View convertView, ViewGroup parent) {
ArtItemHolder holder;
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) this.context).getLayoutInflater();
holder = new ArtItemHolder();
view = inflater.inflate(R.layout.feed_list_item, parent, false);
holder.image = view.findViewById(R.id.img_Image);
holder.pubDate = (TextView) view.findViewById(R.id.txt_puslishDate);
holder.arTitle = (TextView) view.findViewById(R.id.txt_arTitle);
view.setTag(holder);
} else {
holder = (AdvItemHolder) view.getTag();
}
Article ar= articles.get(position);
imgLoader.DisplayImage(ar.getImages().get(0).getUrl(), (ImagePreView) holder.image);
return view;
}
private static class ArtItemHolder{
View image;
TextView pubDate;
TextView arTitle;
}
我的自定义视图
public class ImagePreView extends View{
private static String TAG = "ImagePreView";
private Movie gifImage;
private Bitmap myImage;
Context context;
public ImagePreView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
if (!isInEditMode()) {
new ImagePreView(context, attrs, defStyleAttr);
}
init();
}
public ImagePreView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
this.context = context;
init();
}
public ImagePreView(Context context) {
super(context, null, 0);
this.context = context;
init();
}
private void init(){
setLayerType(View.LAYER_TYPE_SOFTWARE, null);// yada manifeste android:hardwareAccelerated="false" ekle
//setFocusable(true);
InputStream is;
try {
is = context.getResources().getAssets().open("dialogbox_loader.gif");
gifImage = Movie.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDraw(Canvas canvas) {
//canvas.drawColor(0xFFD8D8D8);
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setColor(0xFFA4A4A4);
paint.setStrokeWidth( 2.4f );
paint.setStyle( Style.STROKE );
canvas.drawRect( 0, 0, getWidth(), getHeight(), paint );
super.onDraw(canvas);
if(getWidth() < 1 || getHeight()<1)
requestLayout();
//Log.d(TAG, "WIDTH : " + getWidth()+ ", HEIGHT : " + getHeight());
if(myImage != null){
int width = (getWidth() - myImage.getWidth())/2;
int height = (getHeight() - myImage.getHeight())/2;
canvas.drawBitmap(myImage, width, height, new Paint());
} else if(gifImage != null){
//canvas.drawColor(0, Mode.CLEAR);
//Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//canvas.drawBitmap(b, 0, 0, new Paint());
showLoadingGif(canvas);
}
}
long movieStart ;
private void showLoadingGif(Canvas canvas){
long now = android.os.SystemClock.uptimeMillis();
if (movieStart == 0)
movieStart = now;
int relTime = (int) ((now - movieStart) % gifImage.duration());
gifImage.setTime(relTime);
int width = getWidth()/2 - gifImage.width()/2;
int height = getHeight()/2 - gifImage.height()/2;
gifImage.draw(canvas, width, height);
this.invalidate();
}
public void display(Bitmap bitmap){
this.myImage = getScaledBitmap(bitmap);
invalidate();
}
private Bitmap getScaledBitmap(Bitmap bitmap) {
int viewWidth = getWidth();
int viewHeight = getHeight();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int boundBoxInDp = viewWidth;
if(viewHeight>viewWidth)
boundBoxInDp = viewHeight;
float xScale = ((float) boundBoxInDp) / width;
float yScale = ((float) boundBoxInDp) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
try {
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return scaledBitmap;
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
列表视图项目布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:id="@+id/feed_item_parent">
<TextView
android:id="@+id/txt_arTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@color/main_text_color"
android:textSize="15sp"
android:textStyle="bold"/>
<com.mobile.zenex.component.ImagePreView
android:id="@+id/img_Image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/txt_puslishDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@color/grey_text_color"
android:textSize="15sp"
android:textStyle="bold"/>
</LinearLayout>
尝试使用 Picasso downloading/caching,它可以提高质量/下载速度: