HorizontalListView横着的Listview

先看一下效果图

介可不是什么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<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 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<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(HorizontialListView.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) {
				  Log.i("lkl","ondown@@@@@@" );
				 return HorizontialListView.this.onDown(e);	
				 }	
			 @Override
			 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {	
				 Log.i("lkl","onFling@@@@@@" );
				 return HorizontialListView.this.onFling(e1, e2, velocityX, velocityY);
				 
			 }	
			 @Override
			 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
				 Log.i("lkl","onscroll@@@@@@" );
				 synchronized(HorizontialListView.this){	
					 mNextX += (int)distanceX;	
					 
				 }		
				 requestLayout();	
				 return true;
				 
			 }		
			 @Override
			 public boolean onSingleTapConfirmed(MotionEvent e) {
				 Log.i("lkl","onSingletapConfrimed@@@@@@" );
				 for(int i=0;i<getChildCount();i++){
					 View child = getChildAt(i);
					 
					 if (isEventWithinView(e, child)) {	
						 if(mOnItemClicked != null){
							 mOnItemClicked.onItemClick(HorizontialListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));	
							 
						 }		
						 
						 if(mOnItemSelected != null){	
							 mOnItemSelected.onItemSelected(HorizontialListView.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(HorizontialListView.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()); 
				 
			 }	
			 
		 };
  
}

上面这段代码是自定义的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;
  }
  
 };
 

 

}
里面的数据自己填充哦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值