首先看下效果图,
主要功能分为3大块
一是滑动查看,通过viewpage来实现,方法见 http://www.cnblogs.com/lovemo1314/p/6109312.html
二、点击放大
三、下方的缩略图,横向的listview来完成
点击放大用第三方控件PhotoViewAttacher,支持手指缩放,核心代码
ImageView iv = new ImageView(this); Bitmap bitmap = WebchatAdapter.bitmaps.get(i); iv.setImageBitmap(bitmap); //放大及监听 iv.setScaleType(ImageView.ScaleType.MATRIX); // 这句代码之前必须要现有默认图片来撑开位置 iv.setOnClickListener(this); new PhotoViewAttacher(iv); //NOSON
缩略图采用横向listview, 关于这个控件的资料网上许多地方都有介绍,比如 http://rensanning.iteye.com/blog/2201789
这个控件使用起来很简单,只是把它当作纵向kistview来看就行,需要注意的是,listitem的图片布局必须指定固定的宽高,不然会出现一屏只出现一个缩略图的情况。
首先看横向listview的适配器
public class ThumbnailHorizontalLvAdapter extends MyBaseAdapter<FlagBitmap> { private Context mContext; private LayoutInflater mInflater; private int pre_position; public ThumbnailHorizontalLvAdapter(Context context) { super(); mContext = context; mInflater = LayoutInflater.from(context); } @Override public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.listitem_thumbnail_horizontal, null); } ImageView thumbnailImgView = ViewHolder.getView(convertView, R.id.iv_thumbnail_img); LinearLayout container = ViewHolder.getView(convertView, R.id.ll_item_container); FlagBitmap srcBmp = getItem(position); thumbnailImgView.setScaleType(ImageView.ScaleType.FIT_CENTER); thumbnailImgView.setImageBitmap(srcBmp.getBitmap()); if (srcBmp.isSelected()){ thumbnailImgView.setSelected(true); setViewHeightAndWidth(thumbnailImgView, UnitUtil.dp2Px(mContext,40),UnitUtil.dp2Px(mContext,40)); setPadding(container,UnitUtil.dp2Px(mContext,6), UnitUtil.dp2Px(mContext,6)); }else { thumbnailImgView.setSelected(false); setViewHeightAndWidth(thumbnailImgView, UnitUtil.dp2Px(mContext,30),UnitUtil.dp2Px(mContext,30)); setPadding(container,UnitUtil.dp2Px(mContext,3), UnitUtil.dp2Px(mContext,11)); } return convertView; } public void setSelectImg(int pos) { if (pos != pre_position){ getItem(pos).setSelected(true); getItem(pre_position).setSelected(false); pre_position = pos; notifyDataSetChanged(); } } public void initSelectImgPosition(int pos){ pre_position = pos; } private void setViewHeightAndWidth(View v, float w, float h){ ViewGroup.LayoutParams lp = v.getLayoutParams(); lp.width = (int) w; lp.height = (int) h; v.setLayoutParams(lp); } private void setPadding(View v, float left, float top){ v.setPadding((int)left,(int)top,(int)left,(int)top); } private Bitmap getPropThumnail(Bitmap bm) { // Bitmap bb = BitmapUtil.getRoundedCornerBitmap(b, 100); // int w = mContext.getResources().getDimensionPixelOffset(R.dimen.thumnail_default_width); // int h = mContext.getResources().getDimensionPixelSize(R.dimen.thumnail_default_height); // Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(b, (int) UnitUtil.dp2Px(mContext, 100), // (int) UnitUtil.dp2Px(mContext, 100)); // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 设置想要的大小 int newWidth = 100; int newHeight = 100; // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; float scale = scaleHeight > scaleWidth ? scaleHeight : scaleWidth; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scale, scale); // 得到新的图片 Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(newbm, (int) UnitUtil.dp2Px(mContext, 100), (int) UnitUtil.dp2Px(mContext, 100)); return newbm; } }
MyBaseAdapter.java是我封装的一个适配器的基本模板,在这就不贴出来占空间了,很显然,在上面的代码中我们只重写了getview方法,这才是我们关注的重点,是不是完全与普通的list一样。由于在选中大图后,缩略图要随动更新显示,被选中的图要放大一点,带绿色边框。我这里的思路是通过selector器来实现带绿包边框的效果,而放大的效果则只需把对应的item的imageview宽高设置成比未选中的图片稍大一点,让图片来适配控件。
先来看看listitem的布局,很简单,一个固定宽高的imageview
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_item_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/iv_thumbnail_img" android:layout_width="40dp" android:layout_height="40dp" android:padding="2dp" android:background="@drawable/sel_thumbnail_img" android:src="@drawable/ico_customer_service" /> </LinearLayout>
再来看看图片的背景选择器文件
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/draw_thumbnail_sel_bg" android:state_selected="true" /> <item android:drawable="@drawable/draw_thumbnail_unsel_bg" android:state_selected="false" /> </selector>
选中状态的draw_thumbnail_sel_bg.xml
<?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (c) 2015. Lorem ipsum dolor sit amet, consectetur adipiscing elit. ~ Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. ~ Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. ~ Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. ~ Vestibulum commodo. Ut rhoncus gravida arcu. --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 连框颜色值 --> <item> <shape> <solid android:color="@color/bar_tint"/> <corners android:radius="5dp"/> <size android:width="40dp" android:height="40dp"></size> </shape> </item> <!-- 主体背景颜色值 --> <item android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp"> <!--边框里面背景颜色 白色--> <shape> <corners android:radius="5dp"/> <solid android:color="@android:color/white"/> </shape> </item> </layer-list>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 连框颜色值 --> <item> <shape> <solid android:color="@color/line_back"/> <corners android:radius="5dp"/> <size android:width="30dp" android:height="30dp"></size> </shape> </item> <!-- 主体背景颜色值 --> <item android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp"> <!--边框里面背景颜色 白色--> <shape> <corners android:radius="5dp"/> <solid android:color="@android:color/white"/> </shape> </item> </layer-list>
最后只要把横向listview与viewpage中的大图关联起来就好了。
//缩略图 thumbnailHorizontalLvAdapter = new ThumbnailHorizontalLvAdapter(this); horizontalListView.setAdapter(thumbnailHorizontalLvAdapter); horizontalListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { viewPager.setCurrentItem(position); //缩略图点击后同时刷新大图位置 thumbnailHorizontalLvAdapter.setSelectImg(position); } });
再看大图的适配器
public class KnowcognoViewImagePagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener { private static final String TAG = "state-viewpage-know"; private Context context; private ViewPager viewPager; private List<ImageView> views; private ThumbnailHorizontalLvAdapter thumbnailImgAdapter; public KnowcognoViewImagePagerAdapter(Context context, List<ImageView> viewpages, ViewPager viewPager, ThumbnailHorizontalLvAdapter thumbnailHorizontalLvAdapter) { this.context = context; this.viewPager = viewPager; thumbnailImgAdapter = thumbnailHorizontalLvAdapter; this.viewPager.addOnPageChangeListener(this); views = viewpages; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = (ImageView) views.get(position); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(final int position) { } @Override public void onPageScrollStateChanged(int state) { System.err.println("-------state------>" + state); switch (state) { //在滚动完成之后 case ViewPager.SCROLL_STATE_IDLE: System.err.println("-------state-vitem----->" + viewPager.getCurrentItem()); thumbnailImgAdapter.setSelectImg(viewPager.getCurrentItem()); //滑动完,更新缩略图位置 break; } } }
最后看横向listview的控件,这个也可以去网上找
/* * HorizontalListView.java v1.5 * * * The MIT License * Copyright (c) 2011 Paul Soucy (paul@dev-smart.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ import java.util.LinkedList; import java.util.Queue; import android.content.Context; import android.database.DataSetObserver; import android.graphics.PointF; import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ListAdapter; import android.widget.Scroller; public class HorizontalListView extends AdapterView<ListAdapter> { 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; private OnGestureMoveLinster mOnGestureMoveLinster; private LongClickMonitor mLongClickMonitor; public HorizontalListView(Context context) { super(context); initView(); } public HorizontalListView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public HorizontalListView(Context context, AttributeSet attrs, int styleid ) { super(context, attrs, styleid); 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); mLongClickMonitor = new LongClickMonitor(); } @Override public void setOnItemSelectedListener(OnItemSelectedListener listener) { mOnItemSelected = listener; } @Override public void setOnItemClickListener(OnItemClickListener listener){ mOnItemClicked = listener; } @Override public void setOnItemLongClickListener(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; } public void setOnGestureMoveLinster( OnGestureMoveLinster linster ){ this.mOnGestureMoveLinster = linster; } public void setMaxX( int max ){ mMaxX = max; } //一次滑动一个对象的宽度 private int bakWidth = 0; private int scrollWidth = 0; public void setScrollWidth( int width ){ scrollWidth = width; } public void setNextX(int px){ synchronized(HorizontalListView.this){ mNextX = px; } requestLayout(); } @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) { int bakMaxX = mCurrentX + rightEdge - getWidth(); if( mMaxX == Integer.MAX_VALUE || bakMaxX > mMaxX ){ mMaxX = bakMaxX; } } 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(); } } } private boolean bOnLongPress = false; @Override public boolean dispatchTouchEvent(MotionEvent ev) { if( !bOnLongPress && scrollWidth != 0 ){ comsumeTouchEvent( ev ); return true; }else{ if( bOnLongPress && ev.getAction() == MotionEvent.ACTION_UP ){ bOnLongPress = false; if(mOnGestureMoveLinster!=null && mOnGestureMoveLinster.moveend()){ return true; } } if( bOnLongPress && !mOnGestureMoveLinster.canmove() ) return true; boolean handled = super.dispatchTouchEvent(ev); handled |= mGesture.onTouchEvent(ev); return handled; } } /** 用于记录开始时候的坐标位置 */ private PointF startPoint = new PointF(); private long startPressTime = 0; private boolean move_status = false; public boolean comsumeTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN:{ //AppLog.d(" MoveImageView onTouchEvent ACTION_DOWN "); startPoint.set(event.getRawX(), event.getRawY()); bakWidth = 0; move_status = false; mLongClickMonitor.start(); startPressTime = System.currentTimeMillis(); break; } case MotionEvent.ACTION_MOVE:{ //AppLog.d(" MoveImageView onTouchEvent ACTION_MOVE "); float dx = event.getRawX() - startPoint.x; // 得到x轴的移动距离 float dy = event.getRawY() - startPoint.y; // 得到x轴的移动距离 //避免和双击冲突,大于10f才算是拖动 if(Math.abs(dx) < 40){ break; } move_status = true; if( bakWidth == 0 || bakWidth + ((int)dx) > scrollWidth || bakWidth + ((int)dx) < -scrollWidth ){ bakWidth = (int)dx; if( mNextX == 0 ){ int distance = scrollWidth - scrollWidth/8; mNextX += dx>0?-distance:distance; }else if(mNextX >=mMaxX){ int distance = scrollWidth - scrollWidth/8; mNextX += dx>0?-distance:distance; }else{ int distance = scrollWidth; mNextX += dx>0?-distance:distance; } requestLayout(); }else{ bakWidth += (int)dx; } startPoint.set(event.getRawX(), event.getRawY()); } break; case MotionEvent.ACTION_UP: { mLongClickMonitor.stop(); if( !move_status ){ if( System.currentTimeMillis() - startPressTime < 300 ){ //300ms onClick(); } } move_status = false; //AppLog.d(" MoveImageView onTouchEvent ACTION_UP "); break; } default: break; } return true; } 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) { if( mOnGestureMoveLinster!=null && mOnGestureMoveLinster.moveby( -distanceX, -distanceY ) ){ return true; } 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) { bOnLongPress = true; mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); } break; } } } }; private boolean isEventWithinView(MotionEvent e, View child) { return isEventWithinView( e.getRawX(), e.getRawY(),child ); } private boolean isEventWithinView( float x, float y, View child) { if( scrollWidth!=0 ){ if( x < scrollWidth/8 || x > scrollWidth*9/8 ) return false; } 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)x, (int)y ); } public interface OnGestureMoveLinster{ //返回true 消费事件了 boolean moveby( float dx, float dy ); boolean moveend(); boolean canmove(); } private static final int MSG_LONG = 1; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch ( msg.what ) { case MSG_LONG: onLongClick(); break; } } }; class LongClickMonitor { private final int ST_RUN = 1; private final int ST_STOP = 0; private int run_status = ST_STOP; public LongClickMonitor(){ } public void start(){ if( run_status==ST_RUN ) return; run_status = ST_RUN; startRun(); } public void stop(){ if( run_status == ST_RUN ){ run_status = ST_STOP; } } public void startRun() { new Thread(new Runnable() { @Override public void run() { while( run_status == ST_RUN ){ SystemClock.sleep(10); if( System.currentTimeMillis() - startPressTime >= 1000 ){ //3S handler.sendEmptyMessage( MSG_LONG ); break; } } run_status = ST_STOP; } }).start(); } } private void onLongClick(){ int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (isEventWithinView( startPoint.x, startPoint.y, child)) { if (mOnItemLongClicked != null) { bOnLongPress = true; mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); } break; } } } private void onClick(){ for(int i=0;i<getChildCount();i++){ View child = getChildAt(i); if (isEventWithinView( startPoint.x, startPoint.y, 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; } } } }