HorizontalScrollViewによる複数列ListViewの横スライド(動的ロードを含む)

14912 ワード

AndroidでListViewを使用して複数のデータテーブルを表示する場合、画面幅が足りず、完全に表示できないという問題に遭遇します.以下の例は、私がネット上の様々な案をまとめた良い解です.
カスタムAdapter:
public class HolderAdapter extends BaseAdapter {
	private static final String TAG = "HolderAdapter";

	/**
	 * List    
	 */
	private List 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 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 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を書く
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);
	}
}
public interface LoadStateInterface {
	/*      */
	public void onLoadComplete(List remotDate);
}
/*
 *          
 *     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 mList;

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

		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);
				}
			}
		}
	}
}
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 currentData = RemoteDataUtil.createUpdateData(currentPage,
				pageSize);
		currentPage = currentPage + 1;

		/*
		 * List datas = new ArrayList();
		 * 
		 * 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 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レイアウト



    

    

        

            

                

                

                

                

                

                
            
        
    


説明:実機のテストの時2.2の上でただ時計の頭の横方向でスライドすることを発見します
ソースのダウンロード