diff --git a/devsmartlib/.classpath b/devsmartlib/.classpath
index a4f1e40..3f9691c 100644
--- a/devsmartlib/.classpath
+++ b/devsmartlib/.classpath
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="gen"/>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
-	<classpathentry kind="output" path="bin/classes"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/devsmartlib/.gitignore b/devsmartlib/.gitignore
index 93ca21e..40141f8 100644
--- a/devsmartlib/.gitignore
+++ b/devsmartlib/.gitignore
@@ -1,2 +1,33 @@
-/bin
-/gen
\ No newline at end of file
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Eclipse project files
+.classpath
+.project
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Intellij project files
+*.iml
+*.ipr
+*.iws
+.idea/
+
+
+build.xml
+proguard-project.txt
\ No newline at end of file
diff --git a/devsmartlib/.project b/devsmartlib/.project
index d8e4190..3e0bd66 100644
--- a/devsmartlib/.project
+++ b/devsmartlib/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>DevsmartAndroid</name>
+	<name>_Devsmartlib</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/devsmartlib/libs/android-support-v4.jar b/devsmartlib/libs/android-support-v4.jar
index feaf44f..6080877 100644
Binary files a/devsmartlib/libs/android-support-v4.jar and b/devsmartlib/libs/android-support-v4.jar differ
diff --git a/devsmartlib/src/com/devsmart/android/ui/HorizontalListView.java b/devsmartlib/src/com/devsmart/android/ui/HorizontalListView.java
index 076ed38..e57b0e4 100644
--- a/devsmartlib/src/com/devsmart/android/ui/HorizontalListView.java
+++ b/devsmartlib/src/com/devsmart/android/ui/HorizontalListView.java
@@ -44,334 +44,350 @@
 
 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();
+    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 OnItemLongClickListener mOnItemLongClicked;
+    private boolean mDataChanged = false;
+
+    private enum DownloadType {
+        CACHE, DOWNLOAD, NONE;
+    }
+
+    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
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
+        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
+
+        setMeasuredDimension(MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY));
+    }
+
+    @Override
+    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
+        mOnItemSelected = 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();
+    }
+
+    public static abstract class OnItemUpdateListener {
+
+        public abstract void updateOnStop(AdapterView<?> adapterView, View view, int position, long id);
+
+        public abstract void updateFling(AdapterView<?> adapterView, View view, int position, long id);
+
+    }
+
+    @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);
+        }
+
+        child.setTag(DownloadType.NONE);// update ui
+        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();
+                }
+            });
+
+        }
+
+        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 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) {
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean handled = super.onTouchEvent(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)) {
+                    performItemClick(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);
@@ -382,8 +398,6 @@ private boolean isEventWithinView(MotionEvent e, View child) {
             viewRect.set(left, top, right, bottom);
             return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
         }
-	};
-
-	
+    };
 
 }