自定義Listview實現橫向的HorizontalListView

jopen 11年前發布 | 109K 次閱讀 Android Android開發 移動開發 ListView

先看一下效果圖

自定義Listview實現橫向的HorizontalListView

介可不是什么ScrollView哦,android系統自帶的ListView都是豎著的,這個是橫著的,自定義的ListView,不說了上代碼

package com.zhangyu.activity;
 import java.util.LinkedList;
 import java.util.Queue;
 import android.content.Context;
 import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.util.AttributeSet;
import android.util.Log;
 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 HorizontialListView extends AdapterView {
     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 mRemovedViewQueue = new LinkedList();
     private OnItemSelectedListener mOnItemSelected;    
     private OnItemClickListener mOnItemClicked;    
     private OnItemLongClickListener mOnItemLongClicked;    
     private boolean mDataChanged = false;  
     public HorizontialListView(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(HorizontialListView.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 
  

上面這段代碼是自定義的ListView

下面看一下adapter

package com.zhangyu.activity;

import android.app.Activity; 
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class HorizontalListViewDemo extends Activity {

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

  setContentView(R.layout.main);

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

 };




}
里面的數據自己填充哦

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!