2012-09-20 1 views
1

제목이 약간 지저분한 것을 알고 있지만, 여기에 문제가 있습니다 .... 내 목표는 내 YouTube 채널 비디오의 미리보기 이미지를 그리는 것입니다. 썸네일 URL을 사용하여 listView ... 지금까지 텍스트 제목을 제대로 표시하려면 textView가 있지만 어쨌든 썸네일은 그릴 수 없습니다. ..... 그런데 json/sqlite stuff 클래스가 있습니다. 올바르게 처리하고 데이터를 올바르게 검색 할 수 있으므로 걱정하지 않아도됩니다 ... 나를 괴롭히는 유일한 것은 이미지가 표시되지 않는 축소판입니다. 앱에서 빈 공간으로 imageView가 표시됩니다 ....SimpleCursorAdapter.ViewBinder를 사용하여 URL을 인수로 구문 분석하여 미리보기 이미지를 검색하십시오.

여기에 있습니다. 내 코드, 나에게 손을 줘. 들으

이 활동의에 만드는 방법입니다 ...

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 


    String[] uiBindFrom = { TutListDatabase.COL_TITLE, TutListDatabase.COL_THUMBNAIL }; 
    int[] uiBindTo = { R.id.title, R.id.thumbnail }; 

    getLoaderManager().initLoader(TUTORIAL_LIST_LOADER, null, this); 

    adapter = new SimpleCursorAdapter(
      getActivity().getApplicationContext(), R.layout.list_item, 
      null, uiBindFrom, uiBindTo, 
      CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 
    adapter.setViewBinder(new MyViewBinder()); 
    setListAdapter(adapter); 
} 

이 하나가 목록보기에 물건을 넣어의 개인 클래스입니다 ... 여기

private class MyViewBinder implements SimpleCursorAdapter.ViewBinder{ 

    @Override 
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 
     int viewId = view.getId(); 
     switch(viewId){ 
     case R.id.title: 
      TextView titleTV = (TextView)view; 
      titleTV.setText(cursor.getString(columnIndex)); 
      break; 

        // it is not displaying any thumbnail in app.... 
     case R.id.thumbnail: 
      ImageView thumb = (ImageView) view; 
      thumb.setImageURI(Uri.parse(cursor.getString(columnIndex))); 

     break; 
     } 
     return false; 
    } 

} 

와 인 xml 레이아웃 파일 ...

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:gravity="center_vertical" 
android:orientation="horizontal" > 

<ImageView 
    android:id="@+id/thumbnail" 
    android:layout_width="101dp" 
    android:layout_height="101dp" 
    android:src="@drawable/icon" /> 

<TextView 
    android:id="@+id/title" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:padding="6dp" 
    android:textSize="24dp" /> 


</LinearLayout> 
+0

이미지가 외부 리소스입니까? 네트워크 요청을하면이를 동결시킬 수 있습니다. –

+0

ye. uri는 YouTube의 외부 리소스입니다. 문제를 해결하는 방법은 무엇입니까? 모든 예제가 도움이 될 것입니다 ... – seph

답변

2

나는 내가 사용했던 방법을 보여줄 수 있습니다. 그리고 그것은 아주 잘 작동했습니다. 먼저 우리는 wa가 필요합니다. y를 사용하여 이미지를 캐시하고 내가 본 가장 좋은 방법은 우수한 Google IO 프레젠테이션에 설명 된대로 LruCache를 사용하여 더 적은 작업으로 더 많은 작업을 수행하는 것입니다. 다음은이 프레젠테이션에 설명 된 방법을 구현 한 것입니다. 당신이 만들 필요가

public class LoadImageAsyncTask extends AsyncTask<Void, Void, Pair<Bitmap, Exception>> { 
    private ImageView mImageView; 
    private String mUrl; 
    private BitmapCache mCache; 

    public LoadImageAsyncTask(BitmapCache cache, ImageView imageView, String url) { 
     mCache = cache; 
     mImageView = imageView; 
     mUrl = url; 

     mImageView.setTag(mUrl); 
    } 

    @Override 
    protected void onPreExecute() { 
     Bitmap bm = mCache.get(mUrl); 

     if(bm != null) { 
      cancel(false); 

      mImageView.setImageBitmap(bm); 
     } 
    } 

    @Override 
    protected Pair<Bitmap, Exception> doInBackground(Void... arg0) { 
     if(isCancelled()) { 
      return null; 
     } 

     URL url; 
     InputStream inStream = null; 
     try { 
      url = new URL(mUrl); 
      URLConnection conn = url.openConnection(); 

      inStream = conn.getInputStream(); 

      Bitmap bitmap = BitmapFactory.decodeStream(inStream); 

      return new Pair<Bitmap, Exception>(bitmap, null); 

     } catch (Exception e) { 
      return new Pair<Bitmap, Exception>(null, e); 
     } 
     finally { 
      closeSilenty(inStream); 
     } 
    } 

    @Override 
    protected void onPostExecute(Pair<Bitmap, Exception> result) { 
     if(result == null) { 
      return; 
     } 

     if(result.first != null && mUrl.equals(mImageView.getTag())) { 
      mCache.put(mUrl, result.first); 
      mImageView.setImageBitmap(result.first); 
     } 
    } 

    public void closeSilenty(Closeable closeable) { 
     if(closeable != null) { 
     try { 
      closeable.close(); 
     } catch (Exception e) { 
      // TODO: Log this 
     } 
     } 
    } 
} 

다음 :

public class BitmapCache extends LruCache<String, Bitmap> { 

    public BitmapCache(int sizeInBytes) { 
     super(sizeInBytes); 
    } 

    public BitmapCache(Context context) { 
     super(getOptimalCacheSizeInBytes(context)); 
    } 

    public static int getOptimalCacheSizeInBytes(Context context) { 
     ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 

     int memoryClassBytes = am.getMemoryClass() * 1024 * 1024; 

     return memoryClassBytes/8; 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap value) { 
     return value.getRowBytes() * value.getHeight(); 
    } 
} 

다음으로 우리는 AsyncTask를 비동기 이미지를로드해야합니다, 다음 구현은 주어진 이미지 뷰에 이미지를로드하고 캐시 취급을 담당 에서 onCreate (...) 또는 onActivityCreated에서 ListView에, (...)를 호스팅하는 활동이나 조각에 BitmapCache의 인스턴스 :

mBitmapCache = new BitmapCache(this); // or getActivity() if your using a Fragment 

이제 우리는 최대 필요 날짜, 이미지를 보여주는 SimpleCursorAdapter, 내 프로젝트에 특정 특정 코드 생략 된 있지만 아이디어를 당신이 값을 커서에 바인딩 된 값을 있어야합니다 setViewImage 무시할 수있는, null로 imageview zap. 항목과 연결된 캐시에서 홀수 이미지가 없는지 확인하십시오.

@Override 
    public void setViewImage(ImageView iv, String value) { 
     final String url = value; 
     iv.setImageBitmap(null); 
     new LoadImageAsyncTask(mBitmapCache, iv, url).execute(); 

    } 

업데이트

분명히, 어댑터가 도움이

adapter = new SimpleCursorAdapter(
      context, R.layout.list_item, 
      null, uiBindFrom, uiBindTo, 
      CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER) { 
     @Override 
     public void setViewImage(ImageView iv, String value) { 
       final String url = value; 
       iv.setImageBitmap(null); 
       new LoadImageAsyncTask(mBitmapCache, iv, url).execute(); 
     } 
    }; 

희망처럼 보일 것이다 만들기 위해!

+0

미안 해요, 조금 혼란스러워 ... 어떻게 setViewImage .. overwirte할까요? 그리고 무엇이 ..Closeables.closeSilenty (inStream); ? BitmapCache bm = new BitmapCache (getActivity(). getApplicationContext())를 작성하여 listview를 호스트 하시겠습니까? 나는 논리가 없어졌다.: – seph

+0

죄송합니다. Closeables를 제거하기 위해 업데이트 한 예제 코드에 약간의 오류가 있습니다 .BitmapCache가 작업 또는 조각의 필드 여야합니다. 그런 다음 SimpleCursorAdapter를 수정하고 setViewImage (...)를 재정의해야합니다. –

+0

I 예제 코드를 명확하게 업데이트하여 도움이되기를 바랍니다. –