AndroidでのScrollViewとListViewの共用問題の解決策


転載先:http://blog.csdn.net/l_serein/article/details/6404407
画面容量を超えたコンテンツを1つのインタフェースに配置する必要があり、ScrolViewでスクロールを実現する必要があります.コンテンツをリスト形式で動的に表示するには、ListViewが必要です.しかし、1つのインタフェースで複数のリストを使用して全体的なスクロールを実現しようとすると、ScrollViewとListViewが共用されているときにUIの問題が発生し、所望の効果が得られない.具体的な原因は不明ですが、少なくとも2.1以下は問題があり、Androidのバグの一つでしょう.
実際にはこのような効果を実現するのも難しくありませんが、ListViewを直接使用するのではなく、リストレイアウトを自分で定義し、そのAdapter設定に関する方法を実現する必要があります.そこで私はLinearLayoutから継承されたクラスLinearLayoutForListViewを実現し、Adapter関連メソッドを追加してこの機能を実現しました.
public class LinearLayoutForListView extends LinearLayout {
	private ListAdapter adapter;
	private OnClickListener onClickListener = null;
	private OnTouchListener onTouchListener = null;
	/**
	 *     
	 */
	public void bindLinearLayout() {
		int count = adapter.getCount();
		for (int i = 0; i < count; i++) {
			View v = adapter.getView(i, null, null);
			v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
			v.setOnTouchListener(this.onTouchListener);
			v.setOnClickListener(this.onClickListener);
			v.setId(i);
			addView(v, i);
		}
		Log.v("countTAG", "" + count);
	}
	public LinearLayoutForListView(Context context) {
		super(context);
	}
	public LinearLayoutForListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}
	/**
	 *   Adapter
	 *
	 * @return adapter
	 */
	public ListAdapter getAdpater() {
		return adapter;
	}
	/**
	 *     
	 *
	 * @param adpater
	 */
	public void setAdapter(ListAdapter adpater) {
		this.adapter = adpater;
		bindLinearLayout();
	}
	/**
	 *       
	 *
	 * @return
	 */
	public OnClickListener getOnclickListner() {
		return onClickListener;
	}
	/**
	 *       
	 *
	 * @param onClickListener
	 */
	public void setOnclickLinstener(OnClickListener onClickListener) {
		this.onClickListener = onClickListener;
	}
	public OnTouchListener getOnTouchListener() {
		return onTouchListener;
	}
	public void setOnTouchListener(OnTouchListener onTouchListener) {
		this.onTouchListener = onTouchListener;
	}
}

使用する場合はListViewと同様にBaseAdapterから継承されたクラスオブジェクトをデータソースとして使用します.
private void fillData()
{
	LinearLayoutForListView mSetupList = (LinearLayoutForListView) findViewById(R.id.linear_list);
	mSetupList.setOnclickLinstener(SetupListClickEvent);
	mSetupList.setOnTouchListener(SetupListTouchEvent);
	mSetupList.setAdapter(new ListAdapter(this));
}
public class ListAdapter extends BaseAdapter
{
	private LayoutInflater mInflater;
	public ListAdapter(Context context)
	{
		// Cache the LayoutInflate to avoid asking for a new one each time.
		mInflater = LayoutInflater.from(context);
	}
	/**
	 * The number of items in the list is determined by the number of
	 * speeches in our array.
	 *
	 * @see android.widget.ListAdapter#getCount()
	 */
	public int getCount()
	{
		return this.itemList.length;
	}
	/**
	 * Since the data comes from an array, just returning the index is
	 * sufficent to get at the data. If we were using a more complex data
	 * structure, we would return whatever object represents one row in the
	 * list.
	 *
	 * @see android.widget.ListAdapter#getItem(int)
	 */
	public Object getItem(int position)
	{
		return position;
	}
	/**
	 * Use the array index as a unique id.
	 *
	 * @see android.widget.ListAdapter#getItemId(int)
	 */
	public long getItemId(int position)
	{
		return position;
	}
	/**
	 * Make a view to hold each row.
	 *
	 * @see android.widget.ListAdapter#getView(int, android.view.View,
	 *      android.view.ViewGroup)
	 */
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// Do something or create convertView
		return convertView;
	}
}
View.OnTouchListener SetupListTouchEvent = new View.OnTouchListener() {
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		return false;
	}
};
View.OnClickListener SetupListClickEvent = new View.OnClickListener()
{
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		int position = v.getId();
		...
	}
};