借助HorizontalScrollView实现多列ListView的横向滑动(含动态加载)



在Android中使用ListVIew显示多列数据表时会遇到屏幕宽度不够, 无法完全显示的问题, 以下的例子是我结合网上的各种方案总结的一种较好的解.


自定义Adapter: 

  1. public class HolderAdapter extends BaseAdapter {  
  2.     private static final String TAG = "HolderAdapter";  
  3.   
  4.     /** 
  5.      * List中的数据 
  6.      */  
  7.     private List<Data> currentData;  
  8.     /** 
  9.      * ListView头部 
  10.      */  
  11.     private RelativeLayout mHead;  
  12.     /** 
  13.      * layout ID  
  14.      */  
  15.     private int id_row_layout;  
  16.     private LayoutInflater mInflater;  
  17.   
  18.     int[] colors = { Color.rgb(10210251), Color.rgb(15315351) };  
  19.     // int[] colors = { Color.BLACK, Color.BLACK };  
  20.   
  21.     public HolderAdapter(Context context, int id_row_layout,  
  22.             List<Data> currentData, RelativeLayout mHead) {  
  23.         Log.v(TAG + ".HolderAdapter"" 初始化");  
  24.           
  25.         this.id_row_layout = id_row_layout;  
  26.         this.mInflater = LayoutInflater.from(context);  
  27.         this.currentData = currentData;  
  28.         this.mHead = mHead;  
  29.   
  30.     }  
  31.   
  32.     public int getCount() {  
  33.         // TODO Auto-generated method stub  
  34.         return this.currentData.size();  
  35.     }  
  36.   
  37.     public Object getItem(int position) {  
  38.         // TODO Auto-generated method stub  
  39.         return null;  
  40.     }  
  41.   
  42.     public long getItemId(int position) {  
  43.         // TODO Auto-generated method stub  
  44.         return 0;  
  45.     }  
  46.   
  47.     /** 
  48.      * 向List中添加数据 
  49.      *  
  50.      * @param items 
  51.      */  
  52.     public void addItem(List<Data> items) {  
  53.         for (Data item : items) {  
  54.             currentData.add(item);  
  55.         }  
  56.     }  
  57.   
  58.     /** 
  59.      * 清空当List中的数据 
  60.      */  
  61.     public void cleanAll() {  
  62.         this.currentData.clear();  
  63.     }  
  64.   
  65.     public View getView(int position, View convertView, ViewGroup parentView) {  
  66.         ViewHolder holder = null;  
  67.         if (convertView == null) {  
  68.             convertView = mInflater.inflate(id_row_layout, null);  
  69.             holder = new ViewHolder();  
  70.   
  71.             MyHScrollView scrollView1 = (MyHScrollView) convertView  
  72.                     .findViewById(R.id.horizontalScrollView1);  
  73.   
  74.             holder.scrollView = scrollView1;  
  75.             holder.txt1 = (TextView) convertView.findViewById(R.id.textView1);  
  76.             holder.txt2 = (TextView) convertView.findViewById(R.id.textView2);  
  77.             holder.txt3 = (TextView) convertView.findViewById(R.id.textView3);  
  78.             holder.txt4 = (TextView) convertView.findViewById(R.id.textView4);  
  79.             holder.txt5 = (TextView) convertView.findViewById(R.id.textView5);  
  80.   
  81.             MyHScrollView headSrcrollView = (MyHScrollView) mHead  
  82.                     .findViewById(R.id.horizontalScrollView1);  
  83.             headSrcrollView  
  84.                     .AddOnScrollChangedListener(new OnScrollChangedListenerImp(  
  85.                             scrollView1));  
  86.   
  87.             convertView.setTag(holder);  
  88.             // 隔行变色  
  89.             convertView.setBackgroundColor(colors[position % 2]);  
  90.             // mHolderList.add(holder);  
  91.         } else {  
  92.             // 隔行变色  
  93.             convertView.setBackgroundColor(colors[position % 2]);  
  94.             holder = (ViewHolder) convertView.getTag();  
  95.         }  
  96.         holder.txt1.setText(currentData.get(position).getStr1() + 1 + "列");  
  97.         holder.txt2.setText(currentData.get(position).getStr1() + 2 + "列");  
  98.         holder.txt3.setText(currentData.get(position).getStr1() + 3 + "列");  
  99.         holder.txt4.setText(currentData.get(position).getStr1() + 4 + "列");  
  100.         holder.txt5.setText(currentData.get(position).getStr1() + 5 + "列");  
  101.   
  102.         return convertView;  
  103.     }  
  104.   
  105.     class OnScrollChangedListenerImp implements OnScrollChangedListener {  
  106.         MyHScrollView mScrollViewArg;  
  107.   
  108.         public OnScrollChangedListenerImp(MyHScrollView scrollViewar) {  
  109.             mScrollViewArg = scrollViewar;  
  110.         }  
  111.   
  112.         public void onScrollChanged(int l, int t, int oldl, int oldt) {  
  113.             mScrollViewArg.smoothScrollTo(l, t);  
  114.         }  
  115.     };  
  116.   
  117.     class ViewHolder {  
  118.         TextView txt1;  
  119.         TextView txt2;  
  120.         TextView txt3;  
  121.         TextView txt4;  
  122.         TextView txt5;  
  123.         HorizontalScrollView scrollView;  
  124.     }  
  125.   
  126. }  
public class HolderAdapter extends BaseAdapter {
	private static final String TAG = "HolderAdapter";

	/**
	 * List中的数据
	 */
	private List<Data> currentData;
	/**
	 * ListView头部
	 */
	private RelativeLayout mHead;
	/**
	 * layout ID 
	 */
	private int id_row_layout;
	private LayoutInflater mInflater;

	int[] colors = { Color.rgb(102, 102, 51), Color.rgb(153, 153, 51) };
	// int[] colors = { Color.BLACK, Color.BLACK };

	public HolderAdapter(Context context, int id_row_layout,
			List<Data> currentData, RelativeLayout mHead) {
		Log.v(TAG + ".HolderAdapter", " 初始化");
		
		this.id_row_layout = id_row_layout;
		this.mInflater = LayoutInflater.from(context);
		this.currentData = currentData;
		this.mHead = mHead;

	}

	public int getCount() {
		// TODO Auto-generated method stub
		return this.currentData.size();
	}

	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return null;
	}

	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return 0;
	}

	/**
	 * 向List中添加数据
	 * 
	 * @param items
	 */
	public void addItem(List<Data> items) {
		for (Data item : items) {
			currentData.add(item);
		}
	}

	/**
	 * 清空当List中的数据
	 */
	public void cleanAll() {
		this.currentData.clear();
	}

	public View getView(int position, View convertView, ViewGroup parentView) {
		ViewHolder holder = null;
		if (convertView == null) {
			convertView = mInflater.inflate(id_row_layout, null);
			holder = new ViewHolder();

			MyHScrollView scrollView1 = (MyHScrollView) convertView
					.findViewById(R.id.horizontalScrollView1);

			holder.scrollView = scrollView1;
			holder.txt1 = (TextView) convertView.findViewById(R.id.textView1);
			holder.txt2 = (TextView) convertView.findViewById(R.id.textView2);
			holder.txt3 = (TextView) convertView.findViewById(R.id.textView3);
			holder.txt4 = (TextView) convertView.findViewById(R.id.textView4);
			holder.txt5 = (TextView) convertView.findViewById(R.id.textView5);

			MyHScrollView headSrcrollView = (MyHScrollView) mHead
					.findViewById(R.id.horizontalScrollView1);
			headSrcrollView
					.AddOnScrollChangedListener(new OnScrollChangedListenerImp(
							scrollView1));

			convertView.setTag(holder);
			// 隔行变色
			convertView.setBackgroundColor(colors[position % 2]);
			// mHolderList.add(holder);
		} else {
			// 隔行变色
			convertView.setBackgroundColor(colors[position % 2]);
			holder = (ViewHolder) convertView.getTag();
		}
		holder.txt1.setText(currentData.get(position).getStr1() + 1 + "列");
		holder.txt2.setText(currentData.get(position).getStr1() + 2 + "列");
		holder.txt3.setText(currentData.get(position).getStr1() + 3 + "列");
		holder.txt4.setText(currentData.get(position).getStr1() + 4 + "列");
		holder.txt5.setText(currentData.get(position).getStr1() + 5 + "列");

		return convertView;
	}

	class OnScrollChangedListenerImp implements OnScrollChangedListener {
		MyHScrollView mScrollViewArg;

		public OnScrollChangedListenerImp(MyHScrollView scrollViewar) {
			mScrollViewArg = scrollViewar;
		}

		public void onScrollChanged(int l, int t, int oldl, int oldt) {
			mScrollViewArg.smoothScrollTo(l, t);
		}
	};

	class ViewHolder {
		TextView txt1;
		TextView txt2;
		TextView txt3;
		TextView txt4;
		TextView txt5;
		HorizontalScrollView scrollView;
	}

}


继承LinearLayout写一个容器拦截TouchEvent

  1. public class InterceptScrollContainer extends LinearLayout {  
  2.     private static final String TAG = "InterceptScrollContainer";  
  3.   
  4.     public InterceptScrollContainer(Context context, AttributeSet attrs) {  
  5.         super(context, attrs);  
  6.         // TODO Auto-generated constructor stub  
  7.     }  
  8.   
  9.     public InterceptScrollContainer(Context context) {  
  10.         super(context);  
  11.         // TODO Auto-generated constructor stub  
  12.     }  
  13.   
  14.     /* (non-Javadoc) 
  15.      * @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent) 
  16.      * 拦截TouchEvent 
  17.      */  
  18.     @Override  
  19.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  20.         // TODO Auto-generated method stub  
  21.         Log.i(TAG,"onInterceptTouchEvent");  
  22.         return true;  
  23.         //return super.onInterceptTouchEvent(ev);  
  24.     }  
  25. }  
public class InterceptScrollContainer extends LinearLayout {
	private static final String TAG = "InterceptScrollContainer";

	public InterceptScrollContainer(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public InterceptScrollContainer(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
	 * 拦截TouchEvent
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		Log.i(TAG,"onInterceptTouchEvent");
		return true;
		//return super.onInterceptTouchEvent(ev);
	}
}

  1. public interface LoadStateInterface {  
  2.     /* 加载完成 */  
  3.     public void onLoadComplete(List<Data> remotDate);  
  4. }  
public interface LoadStateInterface {
	/* 加载完成 */
	public void onLoadComplete(List<Data> remotDate);
}

  1. /* 
  2.  * 自定义的 滚动控件 
  3.  * 重载了 onScrollChanged(滚动条变化),监听每次的变化通知给 观察(此变化的)观察者 
  4.  * 可使用 AddOnScrollChangedListener 来订阅本控件的 滚动条变化 
  5.  * */  
  6. public class MyHScrollView extends HorizontalScrollView {  
  7.     ScrollViewObserver mScrollViewObserver = new ScrollViewObserver();  
  8.   
  9.     public MyHScrollView(Context context, AttributeSet attrs, int defStyle) {  
  10.         super(context, attrs, defStyle);  
  11.         // TODO Auto-generated constructor stub  
  12.     }  
  13.   
  14.     public MyHScrollView(Context context, AttributeSet attrs) {  
  15.         super(context, attrs);  
  16.         // TODO Auto-generated constructor stub  
  17.     }  
  18.   
  19.     public MyHScrollView(Context context) {  
  20.         super(context);  
  21.         // TODO Auto-generated constructor stub  
  22.     }  
  23.       
  24.     @Override  
  25.     public boolean onTouchEvent(MotionEvent ev) {  
  26.         return super.onTouchEvent(ev);  
  27.         //return false;  
  28.     }  
  29.   
  30.     @Override  
  31.     protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
  32.         /* 
  33.          * 当滚动条移动后,引发 滚动事件。通知给观察者,观察者会传达给其他的。 
  34.          */  
  35.         if (mScrollViewObserver != null) {  
  36.             mScrollViewObserver.NotifyOnScrollChanged(l, t, oldl, oldt);  
  37.         }  
  38.         super.onScrollChanged(l, t, oldl, oldt);  
  39.     }  
  40.   
  41.     /* 
  42.      * 订阅 本控件 的 滚动条变化事件 
  43.      * */  
  44.     public void AddOnScrollChangedListener(OnScrollChangedListener listener) {  
  45.         mScrollViewObserver.AddOnScrollChangedListener(listener);  
  46.     }  
  47.   
  48.     /* 
  49.      * 取消 订阅 本控件 的 滚动条变化事件 
  50.      * */  
  51.     public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {  
  52.         mScrollViewObserver.RemoveOnScrollChangedListener(listener);  
  53.     }  
  54.   
  55.     /* 
  56.      * 当发生了滚动事件时 
  57.      */  
  58.     public static interface OnScrollChangedListener {  
  59.         public void onScrollChanged(int l, int t, int oldl, int oldt);  
  60.     }  
  61.   
  62.     /* 
  63.      * 观察者 
  64.      */  
  65.     public static class ScrollViewObserver {  
  66.         List<OnScrollChangedListener> mList;  
  67.   
  68.         public ScrollViewObserver() {  
  69.             super();  
  70.             mList = new ArrayList<OnScrollChangedListener>();  
  71.         }  
  72.   
  73.         public void AddOnScrollChangedListener(OnScrollChangedListener listener) {  
  74.             mList.add(listener);  
  75.         }  
  76.   
  77.         public void RemoveOnScrollChangedListener(  
  78.                 OnScrollChangedListener listener) {  
  79.             mList.remove(listener);  
  80.         }  
  81.   
  82.         public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {  
  83.             if (mList == null || mList.size() == 0) {  
  84.                 return;  
  85.             }  
  86.             for (int i = 0; i < mList.size(); i++) {  
  87.                 if (mList.get(i) != null) {  
  88.                     mList.get(i).onScrollChanged(l, t, oldl, oldt);  
  89.                 }  
  90.             }  
  91.         }  
  92.     }  
  93. }  
/*
 * 自定义的 滚动控件
 * 重载了 onScrollChanged(滚动条变化),监听每次的变化通知给 观察(此变化的)观察者
 * 可使用 AddOnScrollChangedListener 来订阅本控件的 滚动条变化
 * */
public class MyHScrollView extends HorizontalScrollView {
	ScrollViewObserver mScrollViewObserver = new ScrollViewObserver();

	public MyHScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public MyHScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public MyHScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		return super.onTouchEvent(ev);
		//return false;
	}

	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		/*
		 * 当滚动条移动后,引发 滚动事件。通知给观察者,观察者会传达给其他的。
		 */
		if (mScrollViewObserver != null) {
			mScrollViewObserver.NotifyOnScrollChanged(l, t, oldl, oldt);
		}
		super.onScrollChanged(l, t, oldl, oldt);
	}

	/*
	 * 订阅 本控件 的 滚动条变化事件
	 * */
	public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
		mScrollViewObserver.AddOnScrollChangedListener(listener);
	}

	/*
	 * 取消 订阅 本控件 的 滚动条变化事件
	 * */
	public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {
		mScrollViewObserver.RemoveOnScrollChangedListener(listener);
	}

	/*
	 * 当发生了滚动事件时
	 */
	public static interface OnScrollChangedListener {
		public void onScrollChanged(int l, int t, int oldl, int oldt);
	}

	/*
	 * 观察者
	 */
	public static class ScrollViewObserver {
		List<OnScrollChangedListener> mList;

		public ScrollViewObserver() {
			super();
			mList = new ArrayList<OnScrollChangedListener>();
		}

		public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
			mList.add(listener);
		}

		public void RemoveOnScrollChangedListener(
				OnScrollChangedListener listener) {
			mList.remove(listener);
		}

		public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {
			if (mList == null || mList.size() == 0) {
				return;
			}
			for (int i = 0; i < mList.size(); i++) {
				if (mList.get(i) != null) {
					mList.get(i).onScrollChanged(l, t, oldl, oldt);
				}
			}
		}
	}
}

  1. public class MainActivity extends Activity implements OnScrollListener {  
  2.     private static final String TAG = "InfoActivity";  
  3.     ListView mListView1;  
  4.     RelativeLayout mHead;  
  5.     LinearLayout main;  
  6.     HolderAdapter holderAdapter;  
  7.     private int last_item_position;// 最后item的位置  
  8.     private boolean isLoading = false;// 是否加载过,控制加载次数  
  9.     private int currentPage = 1;// 当前页,默认为1  
  10.     private int pageSize = 20;// 每页显示十条信息  
  11.     private View loadingView;// 加载视图的布局  
  12.   
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.activity_main);  
  16.   
  17.         mHead = (RelativeLayout) findViewById(R.id.head);  
  18.         mHead.setFocusable(true);  
  19.         mHead.setClickable(true);  
  20.         mHead.setBackgroundColor(Color.BLACK);  
  21.         mHead.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());  
  22.   
  23.         // 加载视图布局  
  24.         loadingView = LayoutInflater.from(this).inflate(  
  25.                 R.layout.list_page_load, null);  
  26.   
  27.         mListView1 = (ListView) findViewById(R.id.listView1);  
  28.         mListView1.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());  
  29.         mListView1.setCacheColorHint(0);  
  30.         // 添加底部加载视图  
  31.         mListView1.addFooterView(loadingView);  
  32.         // 滚动条监听  
  33.         mListView1.setOnScrollListener(this);  
  34.   
  35.         // 创建当前用于显示视图的数据  
  36.         List<Data> currentData = RemoteDataUtil.createUpdateData(currentPage,  
  37.                 pageSize);  
  38.         currentPage = currentPage + 1;  
  39.   
  40.         /* 
  41.          * List<Data> datas = new ArrayList<Data>(); 
  42.          *  
  43.          * for (int i = 0; i < 10; i++) { Data data = new Data(); data.setStr1(i 
  44.          * + "行"); data.setStr2(i + ""); data.setStr3(i + ""); data.setStr4(i + 
  45.          * ""); data.setStr5(i + ""); data.setStr6(i + ""); data.setStr7(i + 
  46.          * ""); data.setStr8(i + ""); datas.add(data); } 
  47.          */  
  48.         holderAdapter = new HolderAdapter(this, R.layout.item, currentData,  
  49.                 mHead);  
  50.         mListView1.setAdapter(holderAdapter);  
  51.         // OnClick监听  
  52.         mListView1.setOnItemClickListener(new OnItemClickListener() {  
  53.   
  54.             public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
  55.                     long arg3) {  
  56.                 // TODO Auto-generated method stub  
  57.                 Log.i("MainActivity ListView""onItemClick Event");  
  58.                 Toast.makeText(MainActivity.this"点了第" + arg2 + "个",  
  59.                         Toast.LENGTH_SHORT).show();  
  60.             }  
  61.         });  
  62.   
  63.     }  
  64.   
  65.     class ListViewAndHeadViewTouchLinstener implements View.OnTouchListener {  
  66.   
  67.         public boolean onTouch(View arg0, MotionEvent arg1) {  
  68.             // 当在列头 和 listView控件上touch时,将这个touch的事件分发给 ScrollView  
  69.             HorizontalScrollView headSrcrollView = (HorizontalScrollView) mHead  
  70.                     .findViewById(R.id.horizontalScrollView1);  
  71.             HorizontalScrollView headSrcrollView2 = (HorizontalScrollView) mHead  
  72.                     .findViewById(R.id.horizontalScrollView1);  
  73.             headSrcrollView.onTouchEvent(arg1);  
  74.             headSrcrollView2.onTouchEvent(arg1);  
  75.             return false;  
  76.         }  
  77.     }  
  78.   
  79.     public void onScroll(AbsListView view, int firstVisibleItem,  
  80.             int visibleItemCount, int totalItemCount) {  
  81.   
  82.         last_item_position = firstVisibleItem + visibleItemCount - 1;  
  83.   
  84.         if (last_item_position == totalItemCount - 2) {  
  85.             // 这里控制当焦点落在某一个位置时,开始加载.  
  86.             // 当前是在第9个位置开始加载,改为totalItemCount-1  
  87.             // 则会在第10个位置开始加载  
  88.   
  89.             /** 
  90.              * Loading 标记当前视图是否处于加载中,如果正在加载(isLoading=true)就不执行更新操作 
  91.              * 加载完成后isLoading=false,在 loadingHandler 中改变状态 
  92.              */  
  93.             if (!isLoading) {  
  94.   
  95.                 // 开启一个线程加载数据  
  96.                 isLoading = true;  
  97.                 RemoteDataUtil.setRemoteDataByPage(currentPage, pageSize,  
  98.                         new LoadStateInterface() {  
  99.                             public void onLoadComplete(List<Data> remotDate) {  
  100.                                 holderAdapter.addItem(remotDate);  
  101.                                 handler.sendEmptyMessage(0);  
  102.                             }  
  103.                         });  
  104.             }  
  105.             ;  
  106.         }  
  107.         ;  
  108.   
  109.         // 当ListView没有FooterView时,添加FooterView(---loadingView---)  
  110.         if (mListView1.getFooterViewsCount() == 0) {  
  111.             handler.sendEmptyMessage(1);  
  112.         }  
  113.     }  
  114.   
  115.     Handler handler = new Handler() {  
  116.         public void handleMessage(android.os.Message msg) {  
  117.             switch (msg.what) {  
  118.             case 0: {  
  119.                 // 更新  
  120.                 holderAdapter.notifyDataSetChanged();  
  121.                 // 删除FooterView  
  122.                 mListView1.removeFooterView(loadingView);  
  123.                 // 进入下一页,此时视图未加载.  
  124.                 isLoading = false;  
  125.                 // 当前页自加  
  126.                 currentPage = currentPage + 1;  
  127.                 break;  
  128.             }  
  129.             case 1: {  
  130.                 mListView1.addFooterView(loadingView);  
  131.                 break;  
  132.             }  
  133.             default: {  
  134.                 Log.w(TAG, "未知的Handler Message:" + msg.obj.toString());  
  135.             }  
  136.             }  
  137.   
  138.         };  
  139.     };  
  140.   
  141.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  142.         // TODO Auto-generated method stub  
  143.   
  144.     }  
  145.   
  146.     /** 
  147.      * 监听ListView的OnItemClick事件 
  148.      *  
  149.      * @param arg0 
  150.      * @param arg1 
  151.      * @param arg2 
  152.      * @param arg3 
  153.      */  
  154.     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
  155.         // TODO Auto-generated method stub  
  156.         Log.i("MainActivity ListView""onItemClick Event");  
  157.         Toast.makeText(MainActivity.this"点了第" + arg2 + "个",  
  158.                 Toast.LENGTH_SHORT).show();  
  159.     }  
  160. }  
public class MainActivity extends Activity implements OnScrollListener {
	private static final String TAG = "InfoActivity";
	ListView mListView1;
	RelativeLayout mHead;
	LinearLayout main;
	HolderAdapter holderAdapter;
	private int last_item_position;// 最后item的位置
	private boolean isLoading = false;// 是否加载过,控制加载次数
	private int currentPage = 1;// 当前页,默认为1
	private int pageSize = 20;// 每页显示十条信息
	private View loadingView;// 加载视图的布局

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mHead = (RelativeLayout) findViewById(R.id.head);
		mHead.setFocusable(true);
		mHead.setClickable(true);
		mHead.setBackgroundColor(Color.BLACK);
		mHead.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());

		// 加载视图布局
		loadingView = LayoutInflater.from(this).inflate(
				R.layout.list_page_load, null);

		mListView1 = (ListView) findViewById(R.id.listView1);
		mListView1.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());
		mListView1.setCacheColorHint(0);
		// 添加底部加载视图
		mListView1.addFooterView(loadingView);
		// 滚动条监听
		mListView1.setOnScrollListener(this);

		// 创建当前用于显示视图的数据
		List<Data> currentData = RemoteDataUtil.createUpdateData(currentPage,
				pageSize);
		currentPage = currentPage + 1;

		/*
		 * List<Data> datas = new ArrayList<Data>();
		 * 
		 * for (int i = 0; i < 10; i++) { Data data = new Data(); data.setStr1(i
		 * + "行"); data.setStr2(i + ""); data.setStr3(i + ""); data.setStr4(i +
		 * ""); data.setStr5(i + ""); data.setStr6(i + ""); data.setStr7(i +
		 * ""); data.setStr8(i + ""); datas.add(data); }
		 */
		holderAdapter = new HolderAdapter(this, R.layout.item, currentData,
				mHead);
		mListView1.setAdapter(holderAdapter);
		// OnClick监听
		mListView1.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// TODO Auto-generated method stub
				Log.i("MainActivity ListView", "onItemClick Event");
				Toast.makeText(MainActivity.this, "点了第" + arg2 + "个",
						Toast.LENGTH_SHORT).show();
			}
		});

	}

	class ListViewAndHeadViewTouchLinstener implements View.OnTouchListener {

		public boolean onTouch(View arg0, MotionEvent arg1) {
			// 当在列头 和 listView控件上touch时,将这个touch的事件分发给 ScrollView
			HorizontalScrollView headSrcrollView = (HorizontalScrollView) mHead
					.findViewById(R.id.horizontalScrollView1);
			HorizontalScrollView headSrcrollView2 = (HorizontalScrollView) mHead
					.findViewById(R.id.horizontalScrollView1);
			headSrcrollView.onTouchEvent(arg1);
			headSrcrollView2.onTouchEvent(arg1);
			return false;
		}
	}

	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {

		last_item_position = firstVisibleItem + visibleItemCount - 1;

		if (last_item_position == totalItemCount - 2) {
			// 这里控制当焦点落在某一个位置时,开始加载.
			// 当前是在第9个位置开始加载,改为totalItemCount-1
			// 则会在第10个位置开始加载

			/**
			 * Loading 标记当前视图是否处于加载中,如果正在加载(isLoading=true)就不执行更新操作
			 * 加载完成后isLoading=false,在 loadingHandler 中改变状态
			 */
			if (!isLoading) {

				// 开启一个线程加载数据
				isLoading = true;
				RemoteDataUtil.setRemoteDataByPage(currentPage, pageSize,
						new LoadStateInterface() {
							public void onLoadComplete(List<Data> remotDate) {
								holderAdapter.addItem(remotDate);
								handler.sendEmptyMessage(0);
							}
						});
			}
			;
		}
		;

		// 当ListView没有FooterView时,添加FooterView(---loadingView---)
		if (mListView1.getFooterViewsCount() == 0) {
			handler.sendEmptyMessage(1);
		}
	}

	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0: {
				// 更新
				holderAdapter.notifyDataSetChanged();
				// 删除FooterView
				mListView1.removeFooterView(loadingView);
				// 进入下一页,此时视图未加载.
				isLoading = false;
				// 当前页自加
				currentPage = currentPage + 1;
				break;
			}
			case 1: {
				mListView1.addFooterView(loadingView);
				break;
			}
			default: {
				Log.w(TAG, "未知的Handler Message:" + msg.obj.toString());
			}
			}

		};
	};

	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// TODO Auto-generated method stub

	}

	/**
	 * 监听ListView的OnItemClick事件
	 * 
	 * @param arg0
	 * @param arg1
	 * @param arg2
	 * @param arg3
	 */
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		// TODO Auto-generated method stub
		Log.i("MainActivity ListView", "onItemClick Event");
		Toast.makeText(MainActivity.this, "点了第" + arg2 + "个",
				Toast.LENGTH_SHORT).show();
	}
}


ListView布局
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:descendantFocusability="blocksDescendants"  
  6.     android:orientation="horizontal"  
  7.     android:padding="5dp" >  
  8.   
  9.     <TextView  
  10.         android:id="@+id/textView1"  
  11.         android:layout_width="80dp"  
  12.         android:layout_height="wrap_content"  
  13.         android:layout_alignParentLeft="true"  
  14.         android:layout_marginLeft="5dp"  
  15.         android:layout_marginRight="5dp"  
  16.         android:textColor="#FFFFFF"  
  17.         android:text="Column1"  
  18.         android:textAppearance="?android:attr/textAppearanceMedium" />  
  19.   
  20.     <com.ytu.mush.hlistview.InterceptScrollContainer  
  21.         android:id="@+id/scroollContainter"  
  22.         android:layout_width="fill_parent"  
  23.         android:layout_height="wrap_content"  
  24.         android:layout_alignParentRight="true"  
  25.         android:layout_toRightOf="@id/textView1"  
  26.         android:focusable="false" >  
  27.   
  28.         <com.ytu.mush.hlistview.MyHScrollView  
  29.             android:id="@+id/horizontalScrollView1"  
  30.             android:layout_width="fill_parent"  
  31.             android:layout_height="wrap_content"  
  32.             android:focusable="false"  
  33.             android:scrollbars="none" >  
  34.   
  35.             <LinearLayout  
  36.                 android:layout_width="match_parent"  
  37.                 android:layout_height="wrap_content"  
  38.                 android:focusable="false"  
  39.                 android:orientation="horizontal" >  
  40.   
  41.                 <TextView  
  42.                     android:id="@+id/textView2"  
  43.                     android:layout_width="80dp"  
  44.                     android:layout_height="wrap_content"  
  45.                     android:layout_marginLeft="5dp"  
  46.                     android:layout_marginRight="5dp"  
  47.                     android:text="Column2"  
  48.                     android:textColor="#FFFFFF"  
  49.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  50.   
  51.                 <TextView  
  52.                     android:id="@+id/textView3"  
  53.                     android:layout_width="80dp"  
  54.                     android:layout_height="wrap_content"  
  55.                     android:layout_marginLeft="5dp"  
  56.                     android:layout_marginRight="5dp"  
  57.                     android:text="Column3"  
  58.                     android:textColor="#FFFFFF"  
  59.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  60.   
  61.                 <TextView  
  62.                     android:id="@+id/textView4"  
  63.                     android:layout_width="80dp"  
  64.                     android:layout_height="wrap_content"  
  65.                     android:layout_marginLeft="5dp"  
  66.                     android:layout_marginRight="5dp"  
  67.                     android:text="Column4"  
  68.                     android:textColor="#FFFFFF"  
  69.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  70.   
  71.                 <TextView  
  72.                     android:id="@+id/textView5"  
  73.                     android:layout_width="80dp"  
  74.                     android:layout_height="wrap_content"  
  75.                     android:layout_marginLeft="5dp"  
  76.                     android:layout_marginRight="5dp"  
  77.                     android:text="Column5"  
  78.                     android:textColor="#FFFFFF"  
  79.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  80.   
  81.                 <TextView  
  82.                     android:id="@+id/textView6"  
  83.                     android:layout_width="80dp"  
  84.                     android:layout_height="wrap_content"  
  85.                     android:layout_marginLeft="5dp"  
  86.                     android:layout_marginRight="5dp"  
  87.                     android:text="Column6"  
  88.                     android:textColor="#FFFFFF"  
  89.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  90.   
  91.                 <TextView  
  92.                     android:id="@+id/textView7"  
  93.                     android:layout_width="80dp"  
  94.                     android:layout_height="wrap_content"  
  95.                     android:layout_marginLeft="5dp"  
  96.                     android:layout_marginRight="5dp"  
  97.                     android:text="Column7"  
  98.                     android:textColor="#FFFFFF"  
  99.                     android:textAppearance="?android:attr/textAppearanceMedium" />  
  100.             </LinearLayout>  
  101.         </com.ytu.mush.hlistview.MyHScrollView>  
  102.     </com.ytu.mush.hlistview.InterceptScrollContainer>  
  103.   
  104. </RelativeLayout>  
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal"
    android:padding="5dp" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:textColor="#FFFFFF"
        android:text="Column1"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <com.ytu.mush.hlistview.InterceptScrollContainer
        android:id="@+id/scroollContainter"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/textView1"
        android:focusable="false" >

        <com.ytu.mush.hlistview.MyHScrollView
            android:id="@+id/horizontalScrollView1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:scrollbars="none" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:focusable="false"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column2"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textView3"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column3"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textView4"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column4"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textView5"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column5"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textView6"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column6"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textView7"
                    android:layout_width="80dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:text="Column7"
                    android:textColor="#FFFFFF"
                    android:textAppearance="?android:attr/textAppearanceMedium" />
            </LinearLayout>
        </com.ytu.mush.hlistview.MyHScrollView>
    </com.ytu.mush.hlistview.InterceptScrollContainer>

</RelativeLayout>

说明: 真机测试的时候发现在2.2上只能在表头横向滑动

源码下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值