0

こんにちは、非同期モードの連絡先画像を読み込む方法が見つかりません。私のコードはハイエンドの携帯電話では問題ないようですが、メモリとプロセッサが少ない携帯電話は遅いです。これは私のアクティビティのコードですonScrollchanged。スクロール

mAdapter = new DialerContactsAdapter(contactos,getActivity());
            listaContactos.setAdapter(mAdapter);
            listaContactos.setFastScrollEnabled(true);
            listaContactos.setOnScrollListener(new OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    switch (scrollState) {
                    case OnScrollListener.SCROLL_STATE_IDLE:
                    mAdapter.mBusy = false;
                    mAdapter.notifyDataSetChanged();
                    break;
                    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        mAdapter.mBusy = false;
                        mAdapter.notifyDataSetChanged();
                    break;
                    case OnScrollListener.SCROLL_STATE_FLING:
                        mAdapter.mBusy = true;
                    break;
                    }
                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem,
                        int visibleItemCount, int totalItemCount) {
                    // TODO Auto-generated method stub

                }
            });

これは私のカスタム アダプターです。「常にデータベースから画像を読み込み、サイズ変更を行い、LruCache クラスに保存します。

@Override  
  public View getView(int position, View convertView, ViewGroup parent) { 
        ViewHolder holder =null; 
      View v = convertView;
      if (v == null) {
          LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          v = vi.inflate(R.layout.dialer_contact_list, null);
          holder = new ViewHolder();
          holder.Picture =  (ImageView) v.findViewById(R.id.imgContactDialer);
          holder.Desc =(TextView) v.findViewById(R.id.txtContactNameDialer);
          holder.phone =(TextView)v.findViewById(R.id.txtContactNumberDialer);
          v.setTag(holder);
      }else
      {
          holder = (ViewHolder)v.getTag();
      }
      final ViewHolder holder2 = holder;
      final ContactInfo ci = (ContactInfo) getItem(position);
      holder2.Picture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent contact = new Intent(context, ShowSingleContactFragment.class);
            contact.putExtra("id", ci.get_id());
            contact.putExtra("name", ci.getDisplayName());
            context.startActivity(contact);
        }
    });
      //genera PlaceHolder
      Bitmap cacheImg =  cache.getBitmapFromMemCache(ci.get_id());
      if(cacheImg==null)
      {
          if(!mBusy)
          {
             new Thread(new Runnable() {
                public void run() {

                    final Bitmap photo= Contacts.loadContactPhoto(ci.get_id(),context.getBaseContext(),context.getResources().getInteger(R.integer.contact_picture_size));
                    cache.addBitmapToMemoryCache(ci.get_id(), photo);
                    holder2.Picture.post(new Runnable() {
                    public void run() {
                        holder2.Picture.setImageBitmap(photo);
                    }
                  });
                }
              }).start();
          }else
          {
              holder.Picture.setImageResource(R.drawable.ic_contact_picture);
          }
      }else
      {
          holder2.Picture.setImageBitmap(cacheImg);
      }
}

これは私の BitmapCache クラスです

public class BitmapCache {
    public  LruCache<String, Bitmap> mMemoryCache;
    public BitmapCache(Context mContext)
    {
         final int memClass = ((ActivityManager) mContext.getSystemService(
                    Context.ACTIVITY_SERVICE)).getMemoryClass();

            // Use 1/8th of the available memory for this memory cache.
            final int cacheSize = 1024 * 1024 * memClass / 8;
            mMemoryCache = new LruCache <String, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    // The cache size will be measured in bytes rather than number of items.
                    return getByteCount(bitmap);
                }
            };
    }
    @SuppressLint("NewApi")
    private int getByteCount(Bitmap bitmap)
    {
        if(Utils.isHoneyComb())
        {
            return bitmap.getByteCount();

        }else
        {
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    }
    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    public Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

}

Android の連絡先リストが見つかりません。誰か助けてもらえますか? どうもありがとう。

4

1 に答える 1

2

@Janmejoyが言ったように、少なくとも私はそう思います。数週間前に同じ問題があったからです。私がしたことは、Lazy loader と ViewHolder を使用することでした。まず、小さな画像の読み込みに問題はありませんでした。ただし、大きな画像は正しくスケーリングされていないようで、表示が悪いことがわかりました。次に、画像を適切にスケーリングできるように、Lazy loader にいくつかの変更を加えました。私のスケーリングコードはこれに基づいています

ImageLoader クラスで変数を定義しDisplayMetrics disMetrics;、コンストラクター内で次のようにしました。disMetrics = new DisplayMetrics();

次のステップは、decodeFile(File file)メソッドにいくつかの変更を加えることでした:

//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();

                   // my custom scaling
        int tw = disMetrics.widthPixels;
        int th = disMetrics.heightPixels;
        int targetWidth = tw <= 0 ? Integer.MAX_VALUE : tw;
        int targetHeight = th <= 0 ? Integer.MAX_VALUE : th;

        int scale = 0;
        while ((o.outWidth >> scale) > targetWidth || (o.outHeight >> scale) > targetHeight) {
            scale++;
        }
                 // native scaling
        //Find the correct scale value. It should be the power of 2.
        //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;
        o2.inSampleSize = 1 << 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;
}

最終的に、私は望んでいた結果を得ることができました。あなたにも役立つことを願っています。

乾杯。

于 2013-01-10T09:34:31.993 に答える