2013-07-18 33 views
1

如何在自定義加載動態圖像ListView iI按照本教程在水平http://www.dev-smart.com/archives/34中顯示ListView但是問題是這個例子使用了相同的示例圖標,但是我想使用我得到的動態圖像從資源或網絡分析如何在自定義ListView中加載動態圖像

Horizo​​ntalListViewDemo.java:

public class HorizontalListViewDemo extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.listviewdemo); 

     HorizontialListView listview = (HorizontialListView) findViewById(R.id.listview); 
     listview.setAdapter(mAdapter); 
    } 

    private static String[] dataObjects = new String[]{ "Text #1", 
     "Text #2", 
     "Text #3" }; 

    private BaseAdapter mAdapter = new BaseAdapter() { 

     @Override 
     public int getCount() { 
      return dataObjects.length; 
     } 

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

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

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      View retval = 
       LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null); 
      TextView title = (TextView) retval.findViewById(R.id.title); 
      title.setText(dataObjects[position]); 

      return retval; 
     } 

    }; 

} 

版式文件:

<linearlayout xmlns:android="http://schemas.android.com/apk/res 
    /android" android:orientation="vertical" 
     android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#fff"> 

    <com.devsmart.android.ui.horizontiallistview android:id="@+id/listview"  
     android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
      android:background="#ddd"> 

     </com.devsmart.android.ui.horizontiallistview> 
      </linearlayout> 

     <linearlayout xmlns:android="http://schemas.android.com 
     /apk/res/android" android:orientation="vertical"  
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" android:background="#fff"> 

    <imageview android:id="@+id/image" 
    android:layout_width="150dip" 
    android:layout_height="150dip" 
    android:scaletype="centerCrop" 
    android:src="@drawable/icon"> 

    <textview android:id="@+id/title" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textcolor="#000" 
     android:gravity="center_horizontal"> 

    </textview></imageview></linearlayout> 

Horizo​​ntalListView.java

public class HorizontalListView extends 
       AdapterView<ListAdapter> { 

public boolean mAlwaysOverrideTouch = true; 
protected ListAdapter mAdapter; 
private int mLeftViewIndex = -1; 
private int mRightViewIndex = 0; 
protected int mCurrentX; 
protected int mNextX; 
private int mMaxX = Integer.MAX_VALUE; 
private int mDisplayOffset = 0; 
protected Scroller mScroller; 
private GestureDetector mGesture; 
private Queue<View> mRemovedViewQueue = new LinkedList<View>(); 
private OnItemSelectedListener mOnItemSelected; 
private OnItemClickListener mOnItemClicked; 
private OnItemLongClickListener mOnItemLongClicked; 
private boolean mDataChanged = false; 


public HorizontalListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initView(); 
} 

private synchronized void initView() { 
    mLeftViewIndex = -1; 
    mRightViewIndex = 0; 
    mDisplayOffset = 0; 
    mCurrentX = 0; 
    mNextX = 0; 
    mMaxX = Integer.MAX_VALUE; 
    mScroller = new Scroller(getContext()); 
    mGesture = new GestureDetector(getContext(), mOnGesture); 
} 

@Override 
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener 

     listener) { 
    mOnItemSelected = listener; 
} 

@Override 
public void setOnItemClickListener(AdapterView.OnItemClickListener listener){ 
    mOnItemClicked = listener; 
} 

@Override 
public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener 
     listener) { 
    mOnItemLongClicked = listener; 
} 

private DataSetObserver mDataObserver = new DataSetObserver() { 

    @Override 
    public void onChanged() { 
     synchronized(HorizontalListView.this){ 
      mDataChanged = true; 
     } 
     invalidate(); 
     requestLayout(); 
    } 

    @Override 
    public void onInvalidated() { 
     reset(); 
     invalidate(); 
     requestLayout(); 
    } 

}; 

@Override 
public ListAdapter getAdapter() { 
    return mAdapter; 
} 

@Override 
public View getSelectedView() { 
    //TODO: implement 
    return null; 
} 

@Override 
public void setAdapter(ListAdapter adapter) { 
    if(mAdapter != null) { 
     mAdapter.unregisterDataSetObserver(mDataObserver); 
    } 
    mAdapter = adapter; 
    mAdapter.registerDataSetObserver(mDataObserver); 
    reset(); 
} 

private synchronized void reset(){ 
    initView(); 
    removeAllViewsInLayout(); 
    requestLayout(); 
} 

@Override 
public void setSelection(int position) { 
    //TODO: implement 
} 

private void addAndMeasureChild(final View child, int viewPos) { 
    LayoutParams params = child.getLayoutParams(); 
    if(params == null) { 
     params = new LayoutParams(LayoutParams.FILL_PARENT, 
     LayoutParams.FILL_PARENT); 
    } 

    addViewInLayout(child, viewPos, params, true); 
    child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), 
      MeasureSpec.makeMeasureSpec(getHeight(), 
     MeasureSpec.AT_MOST)); 
} 



@Override 
protected synchronized void onLayout(boolean changed, int left, int top, int 
    right, int bottom) { 
    super.onLayout(changed, left, top, right, bottom); 

    if(mAdapter == null){ 
     return; 
    } 

    if(mDataChanged){ 
     int oldCurrentX = mCurrentX; 
     initView(); 
     removeAllViewsInLayout(); 
     mNextX = oldCurrentX; 
     mDataChanged = false; 
    } 

    if(mScroller.computeScrollOffset()){ 
     int scrollx = mScroller.getCurrX(); 
     mNextX = scrollx; 
    } 

    if(mNextX <= 0){ 
     mNextX = 0; 
     mScroller.forceFinished(true); 
    } 
    if(mNextX >= mMaxX) { 
     mNextX = mMaxX; 
     mScroller.forceFinished(true); 
    } 

    int dx = mCurrentX - mNextX; 

    removeNonVisibleItems(dx); 
    fillList(dx); 
    positionItems(dx); 

    mCurrentX = mNextX; 

    if(!mScroller.isFinished()){ 
     post(new Runnable(){ 
      @Override 
      public void run() { 
       requestLayout(); 
      } 
     }); 

    } 
} 

private void fillList(final int dx) { 
    int edge = 0; 
    View child = getChildAt(getChildCount()-1); 
    if(child != null) { 
     edge = child.getRight(); 
    } 
    fillListRight(edge, dx); 

    edge = 0; 
    child = getChildAt(0); 
    if(child != null) { 
     edge = child.getLeft(); 
    } 
    fillListLeft(edge, dx); 


} 

private void fillListRight(int rightEdge, final int dx) { 
    while(rightEdge + dx < getWidth() && mRightViewIndex < 
     mAdapter.getCount()) { 

     View child = mAdapter.getView(mRightViewIndex, 
      mRemovedViewQueue.poll(), this); 
     addAndMeasureChild(child, -1); 
     rightEdge += child.getMeasuredWidth(); 

     if(mRightViewIndex == mAdapter.getCount()-1) { 
      mMaxX = mCurrentX + rightEdge - getWidth(); 
     } 

     if (mMaxX < 0) { 
      mMaxX = 0; 
     } 
     mRightViewIndex++; 
    } 

} 

private void fillListLeft(int leftEdge, final int dx) { 
    while(leftEdge + dx > 0 && mLeftViewIndex >= 0) { 
     View child = mAdapter.getView(mLeftViewIndex, 
      mRemovedViewQueue.poll(), this); 
     addAndMeasureChild(child, 0); 
     leftEdge -= child.getMeasuredWidth(); 
     mLeftViewIndex--; 
     mDisplayOffset -= child.getMeasuredWidth(); 
    } 
} 

private void removeNonVisibleItems(final int dx) { 
    View child = getChildAt(0); 
    while(child != null && child.getRight() + dx <= 0) { 
     mDisplayOffset += child.getMeasuredWidth(); 
     mRemovedViewQueue.offer(child); 
     removeViewInLayout(child); 
     mLeftViewIndex++; 
     child = getChildAt(0); 

    } 

    child = getChildAt(getChildCount()-1); 
    while(child != null && child.getLeft() + dx >= getWidth()) { 
     mRemovedViewQueue.offer(child); 
     removeViewInLayout(child); 
     mRightViewIndex--; 
     child = getChildAt(getChildCount()-1); 
    } 
} 

private void positionItems(final int dx) { 
    if(getChildCount() > 0){ 
     mDisplayOffset += dx; 
     int left = mDisplayOffset; 
     for(int i=0;i<getChildCount();i++){ 
      View child = getChildAt(i); 
      int childWidth = child.getMeasuredWidth(); 
      child.layout(left, 0, left + childWidth, 
     child.getMeasuredHeight()); 
      left += childWidth + child.getPaddingRight(); 
     } 
    } 
} 

public synchronized void scrollTo(int x) { 
    mScroller.startScroll(mNextX, 0, x - mNextX, 0); 
    requestLayout(); 
} 

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    boolean handled = super.dispatchTouchEvent(ev); 
    handled |= mGesture.onTouchEvent(ev); 
    return handled; 
} 

protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
    synchronized(HorizontalListView.this){ 
     mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0); 
    } 
    requestLayout(); 

    return true; 
} 

protected boolean onDown(MotionEvent e) { 
    mScroller.forceFinished(true); 
    return true; 
} 

private OnGestureListener mOnGesture = new 
     GestureDetector.SimpleOnGestureListener() { 

    @Override 
    public boolean onDown(MotionEvent e) { 
     return HorizontalListView.this.onDown(e); 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
     return HorizontalListView.this.onFling(e1, e2, velocityX, 
      velocityY); 
    } 

    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, 
      float distanceX, float distanceY) { 

     synchronized(HorizontalListView.this){ 
      mNextX += (int)distanceX; 
     } 
     requestLayout(); 

     return true; 
    } 

    @Override 
    public boolean onSingleTapConfirmed(MotionEvent e) { 
     for(int i=0;i<getChildCount();i++){ 
      View child = getChildAt(i); 
      if (isEventWithinView(e, child)) { 
       if(mOnItemClicked != null){ 

     mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + 
     i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); 
       } 
       if(mOnItemSelected != null){ 

    mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 
    1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); 
       } 
       break; 
      } 

     } 
     return true; 
    } 

    @Override 
    public void onLongPress(MotionEvent e) { 
     int childCount = getChildCount(); 
     for (int i = 0; i < childCount; i++) { 
      View child = getChildAt(i); 
      if (isEventWithinView(e, child)) { 
       if (mOnItemLongClicked != null) { 

    mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 
    1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); 
       } 
       break; 
      } 

     } 
    } 

    private boolean isEventWithinView(MotionEvent e, View child) { 
     Rect viewRect = new Rect(); 
     int[] childPosition = new int[2]; 
     child.getLocationOnScreen(childPosition); 
     int left = childPosition[0]; 
     int right = left + child.getWidth(); 
     int top = childPosition[1]; 
     int bottom = top + child.getHeight(); 
     viewRect.set(left, top, right, bottom); 
     return viewRect.contains((int) e.getRawX(), (int) e.getRawY()); 
    } 
}; 

} 
+0

你在上面的代碼中設置圖像? – Shraddha

回答

1

看看下面的鏈接。有人已經爲它寫了一個庫。

Android Universal Image Loader

我以前this庫在我最近的項目,它完美地工作。

希望它會有所幫助。

+0

我做了,但問題是iage不會顯示只有文本將顯示 – user2589245

+0

文本將正常加載,但這些庫允許您的應用程序延遲加載動態圖像。這些庫將幫助您的應用保持互動,從用戶體驗角度來看這是一件好事。 – Varundroid

+0

Horizo​​ntialListView不支持imageview – user2589245

0

正如@Varundroid說,你可以使用Android的通用圖像加載器,其中工程赫然好。但這是一個巨大的圖書館,用於這麼一個小目的。您可以考慮編寫自己的Asynchronous Image Loader for Android ListView

你可以改變你的適配器類

public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 
     if (convertView == null) { 
      convertView = layoutInflater.inflate(R.layout.list_row_layout, null); 
      holder = new ViewHolder();    
      holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     NewsItem newsItem = (NewsItem) listData.get(position); 
     if (holder.imageView != null) { 
      new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl()); 
     } 
     return convertView; 
    } 

以下對於單獨的線程下載圖像

class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
    private final WeakReference imageViewReference; 

    public ImageDownloaderTask(ImageView imageView) { 
     imageViewReference = new WeakReference(imageView); 
    } 

    @Override 
    // Actual download method, run in the task thread 
    protected Bitmap doInBackground(String... params) { 
     // params comes from the execute() call: params[0] is the url. 
     return downloadBitmap(params[0]); 
    } 

    @Override 
    // Once the image is downloaded, associates it to the imageView 
    protected void onPostExecute(Bitmap bitmap) { 
     if (isCancelled()) { 
      bitmap = null; 
     } 

     if (imageViewReference != null) { 
      ImageView imageView = imageViewReference.get(); 
      if (imageView != null) { 

       if (bitmap != null) { 
        imageView.setImageBitmap(bitmap); 
       } else { 
        imageView.setImageDrawable(imageView.getContext().getResources() 
          .getDrawable(R.drawable.list_placeholder)); 
       } 
      } 

     } 
    } 

} 

上面的鏈接有完整的教程你的目的。

+0

LOL那個lib不是很大。它只是127KB,這是什麼都沒有。 – Varundroid

+0

@Varundroid。同意。你甚至可以考慮lib寬容。(如果你在你的應用程序中使用Universal Image Loader代碼,你應該通知作者它(電子郵件:nostra13 [at] gmail [dot] com):) –

+0

而你的代碼沒有緩存圖像,我提到的libs也緩存圖像在特定的時間段內,這將減少網絡交互,並且會在用戶下次打開應用程序時從緩存中快速加載圖像。請記住,延遲加載的真正動機不僅僅是保持應用程序的交互性,而且還使圖像加載速度更快。 – Varundroid

相關問題