HorizontalScrollViewによる複数列ListViewの横スライド(動的ロードを含む)
14912 ワード
AndroidでListViewを使用して複数のデータテーブルを表示する場合、画面幅が足りず、完全に表示できないという問題に遭遇します.以下の例は、私がネット上の様々な案をまとめた良い解です.
カスタムAdapter:
LinearLayoutを継承してコンテナブロックTouchEventを書く
ListViewレイアウト
説明:実機のテストの時2.2の上でただ時計の頭の横方向でスライドすることを発見します
ソースのダウンロード
カスタム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の上でただ時計の頭の横方向でスライドすることを発見します
ソースのダウンロード