在Android中使用ListVIew顯示多列數據表時會遇到屏幕寬度不夠, 無法完全顯示的問題, 以下的例子是我結合網上的各種方案總結的一種較好的解.
自定義Adapter:
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;
}
}
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<Data> 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<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);
}
}
}
}
}
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();
}
}
<?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上只能在表頭橫向滑動