列表适配器中的圆形图像

时间:2015-05-16 10:01:03

标签: android bitmap android-imageview

我想为每个列表项舍入imageView。我有这个代码来圆形图像:

public class RoundImage extends Drawable {
      private final Bitmap mBitmap;
      private final Paint mPaint;
      private final RectF mRectF;
      private final int mBitmapWidth;
      private final int mBitmapHeight;

      public RoundImage(Bitmap bitmap) {
            mBitmap = bitmap;
            mRectF = new RectF();
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint.setShader(shader);

            mBitmapWidth = mBitmap.getWidth();
            mBitmapHeight = mBitmap.getHeight();
      }

      @Override
      public void draw(Canvas canvas) {
            canvas.drawOval(mRectF, mPaint);
      }

      @Override
      protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mRectF.set(bounds);
      }

      @Override
      public void setAlpha(int alpha) {
            if (mPaint.getAlpha() != alpha) {
                  mPaint.setAlpha(alpha);
                  invalidateSelf();
            }
      }

      @Override
      public void setColorFilter(ColorFilter cf) {
            mPaint.setColorFilter(cf);
      }

      @Override
      public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
      }

      @Override
      public int getIntrinsicWidth() {
            return mBitmapWidth;
      }

      @Override
      public int getIntrinsicHeight() {
            return mBitmapHeight;
      }

      public void setAntiAlias(boolean aa) {
            mPaint.setAntiAlias(aa);
            invalidateSelf();
      }

      @Override
      public void setFilterBitmap(boolean filter) {
            mPaint.setFilterBitmap(filter);
            invalidateSelf();
      }

      @Override
      public void setDither(boolean dither) {
            mPaint.setDither(dither);
            invalidateSelf();
      }

      public Bitmap getBitmap() {
            return mBitmap;
      }

}

这是我的列表适配器代码,我正在尝试使用圆形图像功能,但我收到错误。

public class LazyAdapterConciCiudad extends BaseAdapter {

    // Declare Variables
    Context context;
    LayoutInflater inflater;
    ArrayList<HashMap<String, String>> data;
    ImageLoader imageLoader;
    HashMap<String, String> resultp = new HashMap<String, String>();
    Typeface tf, tf_dos; 

    public LazyAdapterConciertosCiudad(Context context,
            ArrayList<HashMap<String, String>> arraylist, String font, String font_dos) {
        this.context = context;
        data = arraylist;
        imageLoader = new ImageLoader(context);

        tf = Typeface.createFromAsset(context.getAssets(), font);
        tf_dos = Typeface.createFromAsset(context.getAssets(), font_dos);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        // Declare Variables
        TextView id_equipo;
        ImageView escudo_local, escudo_visitante, icono_tv;
        TextView equipo_local, equipo_visitante;
        TextView canal_tv, jornada, dia_hora;
        RoundImage roundedImage;
        Bitmap bitmapa;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.list_row_horarios_liga, parent, false);
        // Get the position
        resultp = data.get(position);

        // Locate the TextViews in listview_item.xml

        jornada = (TextView) itemView.findViewById(R.id.jornada);
        escudo_local = (ImageView) itemView.findViewById(R.id.icono_local);

        Bitmap bitmap = ((BitmapDrawable)escudo_local.getDrawable()).getBitmap();
        roundedImage = new RoundImage(bitmap);
        escudo_local.setImageDrawable(roundedImage);


        equipo_local = (TextView) itemView.findViewById(R.id.equipo_local);
        escudo_visitante = (ImageView) itemView.findViewById(R.id.icono_visitante);
        equipo_visitante = (TextView) itemView.findViewById(R.id.equipo_visitante);
        dia_hora = (TextView) itemView.findViewById(R.id.dia_hora);
        canal_tv = (TextView) itemView.findViewById(R.id.canal_tv);
        icono_tv = (ImageView) itemView.findViewById(R.id.icono_tv);


        dia_hora.setTypeface(tf);
        canal_tv.setTypeface(tf);
        equipo_local.setTypeface(tf_dos);
        equipo_visitante.setTypeface(tf_dos);
        jornada.setTypeface(tf_dos);

        jornada.setText(resultp.get(ConciertosCiudad.TAG_NAME));
        imageLoader.DisplayImage(resultp.get(ConciertosCiudad.TAG_MEDIUM), escudo_local);



        equipo_local.setText(resultp.get(ConciertosCiudad.TAG_NAME_VENUE));
        imageLoader.DisplayImage(resultp.get(ConciertosCiudad.TAG_VENUE_LOGO), escudo_visitante);
        equipo_visitante.setText(resultp.get(ConciertosCiudad.TAG_COUNTRY));
        dia_hora.setText(resultp.get(ConciertosCiudad.TAG_STREET));
        canal_tv.setText(resultp.get(ConciertosCiudad.TAG_STARTDATE));




        return itemView;
    }
}

我收到此代码的错误:

Bitmap bitmap = ((BitmapDrawable)escudo_local.getDrawable()).getBitmap();
            roundedImage = new RoundImage(bitmap);
            escudo_local.setImageDrawable(roundedImage);

这是我的日志猫:

05-16 12:08:28.762: E/AndroidRuntime(25969): FATAL EXCEPTION: main
05-16 12:08:28.762: E/AndroidRuntime(25969): Process: my.package.feed, PID: 25969
05-16 12:08:28.762: E/AndroidRuntime(25969): java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference
05-16 12:08:28.762: E/AndroidRuntime(25969):    at my.package.feed.LazyAdapterConciertosCiudad.getView(LazyAdapterConciertosCiudad.java:77)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.AbsListView.obtainView(AbsListView.java:2346)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.ListView.onMeasure(ListView.java:1182)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1456)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:875)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:762)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:447)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2815)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.View.measure(View.java:17429)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5786)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.Choreographer.doCallbacks(Choreographer.java:580)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.Choreographer.doFrame(Choreographer.java:550)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.os.Handler.handleCallback(Handler.java:739)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.os.Handler.dispatchMessage(Handler.java:95)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.os.Looper.loop(Looper.java:135)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at android.app.ActivityThread.main(ActivityThread.java:5254)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at java.lang.reflect.Method.invoke(Native Method)
05-16 12:08:28.762: E/AndroidRuntime(25969):    at java.lang.reflect.Method.invoke(Method.java:372)
05-16 12:08:28.762: E/AndroidRuntime(25969):    a

这是我的Image Loader:

public class ImageLoader {

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections
            .synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    // Handler to display images in UI thread
    Handler handler = new Handler();

    public ImageLoader(Context context) {
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
    }

    //No lo uso para nada
    final int stub_id = R.drawable.ic_action_about;

    public void DisplayImage(String url, ImageView imageView) {
        imageViews.put(imageView, url);
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null)
            imageView.setImageBitmap(bitmap);
        else {
            queuePhoto(url, imageView);
            //imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView) {
        PhotoToLoad p = new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // Download Images from the Internet
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl
                    .openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    // Decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.
            // Recommended Size 512
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // Task for the queue
    private class PhotoToLoad {
        public String url;
        public ImageView imageView;

        public PhotoToLoad(String u, ImageView i) {
            url = u;
            imageView = i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                if (imageViewReused(photoToLoad))
                    return;
                Bitmap bmp = getBitmap(photoToLoad.url);
                memoryCache.put(photoToLoad.url, bmp);
                if (imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);
        if (tag == null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;
            if (bitmap != null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            //else
                //photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

}

有人知道为什么或我可以解决它?非常感谢你

2 个答案:

答案 0 :(得分:1)

我建议您使用universal image loader进行图像加载,并使用圆角图像在图像加载器中使用DisplayImageOptions。

作为

DisplayImageOptions userimgoptions = new DisplayImageOptions.Builder()
                       .displayer(new RoundedBitmapDisplayer((int) 50.0f))
                       .showImageOnLoading(android.R.color.transparent)
                       .showImageForEmptyUri(R.drawable.picture_info_profile_img)
                       .showImageOnFail(R.drawable.picture_info_profile_img)
                       .cacheInMemory(true).cacheOnDisc(true)
                       .bitmapConfig(Bitmap.Config.ARGB_8888).build();

这里50.0f是半径像素。

答案 1 :(得分:0)

escudo_local之前将getDrawable中的一些位图放在xml资源中的init或者从web加载,例如。

试用BitmapDisplayer的代码:

 class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;
            if (bitmap != null)
                photoToLoad.imageView.setImageDrawable(new RoundImage(bitmap));
            //else
                //photoToLoad.imageView.setImageResource(stub_id);
        }
    }

并删除

Bitmap bitmap = ((BitmapDrawable)escudo_local.getDrawable()).getBitmap();
roundedImage = new RoundImage(bitmap);
escudo_local.setImageDrawable(roundedImage);

来自适配器。