Android ImageView 在 ListView 中呈现更小的位图图像

Posted

技术标签:

【中文标题】Android ImageView 在 ListView 中呈现更小的位图图像【英文标题】:Android ImageView is rendering Bitmap images smaller while in ListView 【发布时间】:2019-04-24 04:07:33 【问题描述】:

我有一个ListView,在linear layout 内,它应该显示基于list_item.xml 布局文件的项目。在布局文件中,我有两个ImageViews 和两个TextViews。我正在使用我的自定义ArrayAdapter 在运行时用Bitmap 比例125x25 的图像填充ListView,但是当内部的ImageView 渲染时,图像显示的尺寸小于它们的初始尺寸ListView 如下面的屏幕截图(单个列表项)所示:

ActivityLayout.xml:

...
<LinearLayout
    android:layout_
    android:layout_
    android:layout_alignParentStart="true"
    android:paddingTop="40dp"
    android:orientation="vertical">

    <ListView
        android:id="@+id/lvExp"
        android:layout_
        android:layout_ />

</LinearLayout>
...

List_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:minHeight="?android:attr/listPreferredItemHeight">

    <ImageView
        android:id="@+id/imageViewplate"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="true"
        android:minWidth="300dp" />

    <TextView
        android:id="@+id/lblListItem_letter"
        android:layout_
        android:layout_
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/imageViewplate"
        android:padding="3dp"
        android:text="A"
        android:textSize="17dip" />

    <TextView
        android:id="@+id/lblListItem_num"
        android:layout_
        android:layout_
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/lblListItem_letter"
        android:padding="3dp"
        android:text="123456"
        android:textSize="17dip" />

    <ImageView
        android:id="@+id/imageViewchars"
        android:layout_
        android:layout_
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="10dp"
        android:paddingTop="3dp"
        android:paddingBottom="3dp" />

</RelativeLayout>

我的自定义列表适配器:

    package bi.anpr.layouts;

import android.content.Context;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.sxx.vlctest.R;

import java.util.ArrayList;

import bi.anpr.agents.Plate;

public class PlateListAdapter extends ArrayAdapter<Plate>

    public PlateListAdapter(Context context, int resource) 
        super(context, resource);
    

    private ArrayList<Plate> dataSet;
    Context mContext;

    private static class ViewHolder 
        public ImageView imageView_plate, imageView_chars;
        public TextView textView_letter, textView_numbers;
    

    private int lastPosition = -1;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        // Get the data item for this position
        Plate plate = getItem(position);
        ViewHolder viewHolder;
        final View result;

        if (convertView == null) 
            viewHolder = new ViewHolder();

            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.list_item, parent, false);

            viewHolder.textView_letter = (TextView) convertView.findViewById(R.id.lblListItem_letter);
            viewHolder.textView_numbers = (TextView) convertView.findViewById(R.id.lblListItem_num);
            viewHolder.imageView_plate = (ImageView) convertView.findViewById(R.id.imageViewplate);
            viewHolder.imageView_chars = (ImageView) convertView.findViewById(R.id.imageViewchars);
            result = convertView;

            convertView.setTag(viewHolder);
         else 
            viewHolder = (ViewHolder) convertView.getTag();
            result = convertView;
        

        lastPosition = position;

        try
            viewHolder.imageView_plate.setImageBitmap(plate.getEngPartImageIcon());
            viewHolder.imageView_chars.setImageBitmap(plate.getcharsImageIcon());
            viewHolder.textView_letter.setText(Character.toString(plate.getPlateLetter()));
            viewHolder.textView_numbers.setText(plate.getPlateNumbersAsString());
        catch (Exception e)
            e.printStackTrace();
        


        // Return the completed view to render on screen
        return convertView;
    

Plate.java:

package bi.anpr.agents;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;

import java.io.Serializable;
import java.util.ArrayList;


import org.opencv.core.Mat;
import org.opencv.core.Rect;

import bi.anpr.core.IPHelper;

public class Plate implements Serializable 

    private String platePath;
    private boolean isWidePlate = true;
    private int[] color;
    private String colorString;
    private String source = "";
    private Rect bdgbx;
    private Mat srcImage;
    private Mat plateImage;
    private Bitmap engPartImageIcon, plateImageIcon, forCutImageIcon, charsImageIcon, charsTextImageIcon;
    private Mat engPartImage;
    private Mat forCut;
    private ArrayList<Character> plateNumberChars = new ArrayList<>();
    private char plateLetterChar = '#';
    private String fullPlateString = "";
    private String numbersPlateString = "";
    private double letterRate = 0;
    private double numbersRate = 0;
    private double accuracy = 0;
    private int id;
    private PlateRecogInfo plateRecogInfo;
    private ArrayList<Bitmap> charsIcons = new ArrayList<>();
    private boolean ignore = false;
    private int accurayPercent = 0;

    public Plate() 
        plateRecogInfo = new PlateRecogInfo();
    

    public void addPlateNumberChar(char c) 
        plateNumberChars.add(c);
    

    public Bitmap getplateImageIcon() 
        return plateImageIcon;
    

    public void setPlateImageIcon(Bitmap plateImageIcon) 
        this.plateImageIcon = plateImageIcon;
    

    public Bitmap getEngPartImageIcon() 
        if (engPartImageIcon == null) 
            engPartImageIcon = IPHelper.matToBitmap(engPartImage);
        
        return engPartImageIcon;
    

    public void setEngPartImageIcon(Bitmap engPartImageIcon) 
        this.engPartImageIcon = engPartImageIcon;
    

    public Mat getEngPartImage() 
        return engPartImage;
    

    public void setEngPartImage(Mat engPartImage) 
        this.engPartImage = engPartImage;
    

    public boolean isWidePlate() 
        return isWidePlate;
    

    public void setWidePlate(boolean isWidePlate) 
        this.isWidePlate = isWidePlate;
    

    public Mat getImage() 
        return plateImage;
    

    public void setImage(Mat Bitmap) 
        plateImage = Bitmap;
    

    public Bitmap getForCutImageIcon() 
        if (forCutImageIcon == null) 
            forCutImageIcon = IPHelper.matToBitmap(forCut);
        
        return forCutImageIcon;
    

    public Mat getForCut() 
        return forCut;
    

    public void setForCutImageIcon(Bitmap forCutImageIcon) 
        this.forCutImageIcon = forCutImageIcon;
    

    public void setForCut(Mat forCut) 
        this.forCut = forCut;
    

    public ArrayList<Character> getPlateNumberChar() 
        return plateNumberChars;
    

    public void setPlateNumberChar(ArrayList<Character> nchar) 
        plateNumberChars = new ArrayList<Character>(nchar);
    

    public char getPlateLetter() 
        return plateLetterChar;
    

    public void setPlateLetter(char plateLetter) 
        plateLetterChar = plateLetter;
    

    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

    public double getLetterRate() 
        return letterRate;
    

    public void setLetterRate(double letterRate) 
        this.letterRate = letterRate;
    

    public double getCharsRate() 
        return numbersRate;
    

    public void setNumbersRate(double NumbersRate) 
        this.numbersRate = NumbersRate;
    

    public double getAccuracy() 
        return accuracy;
    

    public int getAccurayPercent() 
        return accurayPercent;
    

    public void setAccuracy(double totalRate) 
        this.accuracy = totalRate;
        this.accurayPercent = (int) (totalRate * 100);
    

    public Mat getPlateImage() 
        return plateImage;
    

    public void setPlateImage(Mat matImage) 
        this.plateImage = matImage;
        plateImageIcon = IPHelper.matToBitmap(matImage);
    

    public PlateRecogInfo getPlateRecogInfo() 
        return plateRecogInfo;
    

    public void setPlateRecogInfo(PlateRecogInfo plateRecogInfo) 
        this.plateRecogInfo = plateRecogInfo;
    

    public void addCharIcon(Mat charsIcons) 
        this.charsIcons.add(IPHelper.matToBitmap(charsIcons));
    

    public Bitmap getcharsImageIcon() 
        if (charsImageIcon == null) 
            int width = 5;
            int height = 0;
            for (Bitmap icon : charsIcons) 
                if (icon.getHeight() > height)
                    height = icon.getHeight();
                width += icon.getWidth() + 5;
            
            height += 6;

            charsImageIcon = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(charsImageIcon);

            int i = 0;
            for (Bitmap icon : charsIcons) 
                canvas.drawBitmap(icon, i, 3, null);
                i += icon.getWidth() + 5;
            
        

        return charsImageIcon;
    

    public Bitmap getCharsTextImageIcon() 
        if (charsTextImageIcon == null) 
            String chars = "";
            for (Character c : plateNumberChars) 
                String cs = c.toString();
                chars += cs;
            

            int width = 5;
            int height = 0;
            for (Bitmap icon : charsIcons) 
                if (icon.getHeight() > height)
                    height = icon.getHeight();
                width += icon.getWidth() + 5;
            
            height += 6;

            charsTextImageIcon = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(charsTextImageIcon);

            int i = 0;
            int j = 0;

            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
            paint.setColor(Color.BLACK);
            paint.setTextSize(16);

            canvas.drawColor(Color.WHITE);

            for (Bitmap icon : charsIcons) 

                if (j == 0)
                    canvas.drawText("Some Text", i + 2, 19, paint);
                else
                    canvas.drawText(Character.toString(chars.charAt(j - 1)), i + 3, 19, paint);

                i += icon.getWidth() + 5;
                j++;
            

        

        return charsTextImageIcon;
    

    public void setCharsTextImageIcon(Bitmap charsTextImageIcon) 
        this.charsTextImageIcon = charsTextImageIcon;
    

    public Mat getSrcImage() 
        return srcImage;
    

    public void setSrcImage(Mat srcImage) 
        this.srcImage = srcImage;
    

    public Rect getBdgbx() 
        return bdgbx;
    

    public void setBdgbx(Rect bdgbx) 
        this.bdgbx = bdgbx;
    

    public int[] getColor() 
        return color;
    

//    public Color getColorObject() 
//        int[] color = getColor();
//
//        try 
//            return Color.parseColor(Color.rgb(color[0], color[1], color[2]));
//         catch (Exception e) 
//        
//        return null;
//    

    public void setColor(int[] is) 
        this.color = is;
    

    public String getColorString() 
        return colorString;
    

    public void setColorString(String colorString) 
        this.colorString = colorString;
    

    public String getFullPlateCharsString() 
        if (fullPlateString == "" || fullPlateString == null) 
            fullPlateString += plateLetterChar;
            for (Character c : plateNumberChars) 
                fullPlateString += c.toString();
            
        

        return fullPlateString;
    

    public void setFullPlateString(String fullPlateString) 
        this.fullPlateString = fullPlateString;
    

    public void setNumbersPlateString(String numbersPslateString) 
        this.numbersPlateString = numbersPslateString;
    

    public String getPlateNumbersAsString() 
        if (numbersPlateString == "" || numbersPlateString == null) 
            for (Character c : plateNumberChars) 
                numbersPlateString += c.toString();
            
        

        return numbersPlateString;
    

    public String getPlatePath() 
        return platePath;
    

    public void setPlatePath(String platePath) 
        this.platePath = platePath;
    

    public boolean isIgnore() 
        return ignore;
    

    public void setIgnore(boolean ignore) 
        this.ignore = ignore;
    

    public String getSource() 
        return source;
    

    public void setSource(String source) 
        this.source = source;
    


用法:

PlateListAdapter plateListAdapter = new PlateListAdapter(getApplicationContext(), R.layout.list_item);
ListView resultsListView = (ListView) findViewById(R.id.lvExp);
resultsListView.setAdapter(plateListAdapter);
plateListAdapter.addAll(recogInfo.getPlates());
plateListAdapter.notifyDataSetChanged();

【问题讨论】:

【参考方案1】:

ImageView 使用确定的尺寸,而不是wrap_content 解决了这个问题。

【讨论】:

以上是关于Android ImageView 在 ListView 中呈现更小的位图图像的主要内容,如果未能解决你的问题,请参考以下文章

android 自定义控件(带有删除按钮的imageview) 怎么在ImageView背景上添加button按钮 动态添加imageview 自带删除图标的imageview list删除某

Android - 在 ImageView 周围设置边框

Android ImageView(scaleType属性)

android中关于ImageView的问题

如何在 Android 中水平滚动 ImageView?

Android 在 ImageView 中绘制边框