您的位置:首页 > 移动开发 > Android开发

android 横向listview

2015-12-14 11:34 387 查看
第一步:定义xml

  <com.beijingmeifu.teacherclient.activity.read_teachingmaterials.HorizontalListView

                android:id="@+id/listView"

                android:layout_width="wrap_content"

                android:layout_height="match_parent"

                android:layout_gravity="center"

                android:divider="#cccccc"   

                 >

            </com.beijingmeifu.teacherclient.activity.read_teachingmaterials.HorizontalListView>

第二步:实现自定义的类

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

 第三步:自定义adapter

public class ReadTeachingmaterialsAdapter extends BaseAdapter

{

Context context;
List<Map<String, Object>> list=null;
LayoutInflater inflater;
 private int selectIndex = -1;  
public ReadTeachingmaterialsAdapter(Context context,List<Map<String, Object>> list)
{
inflater=LayoutInflater.from(context);
this.context=context;
this.list=list;
}

@Override
public int getCount()
{
return list.size();
}

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

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

@Override
public View getView(int arg0, View arg1, ViewGroup arg2)
{
ViewHolder viewHolder=null;
if (arg1==null)
{
viewHolder=new ViewHolder();
arg1=inflater.inflate(R.layout.activity_read_reachingmaterials_item, null);
viewHolder.textView=(TextView)arg1.findViewById(R.id.textView);
viewHolder.imageView=(ImageView)arg1.findViewById(R.id.imageView);
arg1.setTag(viewHolder);
}
else {
viewHolder=(ViewHolder)arg1.getTag();
}
 if(arg0 == selectIndex){  
 arg1.setSelected(true);  
       }else{  
       
arg1.setSelected(false);  
       }  
viewHolder.textView.setText((String)list.get(arg0).get("textView"));
viewHolder.imageView.setImageBitmap((Bitmap)list.get(arg0).get("imageView"));
return arg1;
}

public class ViewHolder
{
public TextView textView;
public ImageView imageView;
}
public void setSelectIndex(int i){  
       selectIndex = i;  
   }  

}

第四步:定义item布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:orientation="vertical" 

    android:paddingLeft="2dip"  

    android:paddingRight="2dip"  

    android:paddingTop="2dip"  

    android:paddingBottom="2dip"  

    android:gravity="center"  

    android:clickable="true"  

    android:background="@drawable/bookselector">

    <TextView

            android:id="@+id/textView"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="center"

            android:text="教材名称"

            android:textColor="@color/white"

            android:textSize="15sp" />

        <ImageView

            android:id="@+id/imageView"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:adjustViewBounds="true" 

            android:layout_margin="5dp"

            />

        <!--

         android:layout_width="225dp"

        android:layout_height="290dp"

        android:adjustViewBounds="true"

            android:background="@drawable/border"

        -->

注:item选择点击状态改变<selector xmlns:android="http://schemas.android.com/apk/res/android" >

     <item android:drawable="@android:color/holo_blue_bright" android:state_selected="true"/>  

    <item android:drawable="@android:color/holo_blue_bright" android:state_pressed="true"/>  

    <item android:drawable="@android:color/transparent"/>  

</selector>

        

</LinearLayout>

第五步:将list和adapter绑定,并设置子项监听

readTeachingmaterialsAdapter = new ReadTeachingmaterialsAdapter(
Read_TeachingmaterialsActivity.this, list);
horizontalListView.setAdapter(readTeachingmaterialsAdapter);
horizontalListView.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3)
{
SaveToListCurrentPage();
// 获取教材的总页数
totalPage = (Integer) list.get(arg2).get("total");
// 显示在界面上
totalTextView.setText(totalPage + "");
// 记录当前选择的教材
bookName = (String) list.get(arg2).get("textView");
boolean IsRead = false;
for (Map<String, Object> item : listCurrent)
{
if (bookName.equals(item.get("name")))
{
IsRead = true;
// 获取上一次读到哪一页
currentPage = Integer.parseInt(item.get("currentPage")
.toString());
}
}
// 判断教材是否已读过
if (IsRead)
{
// 显示当前页
imageView.setImageBitmap(getBitmap2(path + bookName + "/"
+ currentPage + ".jpg"));
} else
{
currentPage = 1;
// 显示第一页
imageView.setImageBitmap(getBitmap2(path + bookName
+ "/1.jpg"));
}
// 设置当前显示的页码
setCurrentPage();
readTeachingmaterialsAdapter.setSelectIndex(arg2);
readTeachingmaterialsAdapter.notifyDataSetChanged();
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: