ListView本身就含有ScrollView,因此把ListView放到ScrollView中会引起混乱(谁来响应滑动事件?)但有时又确有此需求,以实现ListView的内容连同其他内容的滚动。
要想把ListView嵌入ScrollView,有二个方法:
方法1:整体上使用一个ListView, 把不需滚动的部分放入ListView的Header或Footer中。
注意: 一定要先添加HearderView和FooterView,然后再设置ListView的Adapter. 缺陷: Header或Footer中的内容不能滚动;并且只能允许同时存在一个ListView。 代码如下: LayoutInflater mLI =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); listView = (ListView) findViewById(R.id.listView);
datas = new ArrayList<Object>(); fillDatas(); datasAdapter = new DemoListAdapter(context, datas); MyListHeaderView headerView = mLI.inflate(R.layout.my_header_layout, null); FillDataToHeaderView(headerView); MyListFooterView footerView = mLI.inflate(R.layout.my_footer_layout, null); FillDataToFooterView(footerView); listView.addHeaderView(headerView);
listView.addFooterView(footerView); listView.setAdapter(datasAdapter); 方法2:用LinearLayout模拟ListView, 从而实现任意内容的滚动。 下面实现的是一个通用的LinearLayoutForListView,可以为它设置不同的Adapter从而显示不同的数据。 LinearLayoutForListView的代码如下: public class LinearLayoutForListView extends android.widget.LinearLayout {
static final String LOG_TAG = "LinearLayoutForListView"; private android.widget.BaseAdapter adapter; private OnClickListener onClickListener = null; public void fillLinearLayout() {
int count = adapter.getCount(); for (int i = 0; i < count; i++) { View v = adapter.getView(i, null, null); v.setOnClickListener(this.onClickListener); addView(v, i); } Log.v("countTAG", "" + count); } public LinearLayoutForListView(Context context) {
super(context); } public LinearLayoutForListView(Context context, AttributeSet attrs) {
super(context, attrs); } public android.widget.BaseAdapter getAdpater() {
return adapter; } public void setAdapter(android.widget.BaseAdapter adpater) {
this.adapter = adpater; fillLinearLayout(); } public OnClickListener getOnclickListner() {
return onClickListener; } public void setOnclickLinstener(OnClickListener onClickListener) {
this.onClickListener = onClickListener; } } 注意,上面LinearLayoutForListView的成员adapter是BaseAdapter,因此可以自定义其它的Adapter来加入数据。下面是一个Adapter的参考实现,用于显示一个软件开发者的联系信息:
public class DeveloperInfoAdapter extends BaseAdapter {
static final String LOG_TAG="DeveloperInfo"; public final int VIEW_INDEX = 3000; private Context mContext; private String[] mKeys; private String[] mTitles; private String[] mVals; LayoutInflater mLI = null; public DeveloperInfoAdapter(Context context, String[] keys, String[] titles, String[] vals) {
mContext = context; mKeys = keys; mTitles = titles; mVals = vals; mLI = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // to Make sure mKeys(...) are NOT null: if(mKeys==null || mTitles==null || mVals==null) { mKeys = mTitles = mVals = new String[]{}; } } @Override public int getCount() { return mKeys.length; } @Override public String getItem(int index) { if(index>=0 && index<mVals.length) return mVals[index]; else return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if(position <0 || position > mKeys.length) return null; final String key = mKeys[position]; final String title = mTitles[position]; final String val = mVals[position]; View v = convertView; if (v == null) { v = mLI.inflate(R.layout.dev_web_email_layout, null); } v.setId(position+VIEW_INDEX); v.setClickable(true); if (true) { TextView v_title = (TextView) v.findViewById(R.id.dev_title); TextView v_val = (TextView) v.findViewById(R.id.dev_val); v_title.setText(title); v_val.setText(val); } return v; } private void callBrowser(String url){ if(TextUtils.isEmpty(url)) return; final String prefix = "http://"; try { if(!url.startsWith(prefix)) url = prefix + url; Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); mContext.startActivity(intent); } catch (Exception e) { String err_msg = e.getMessage(); Log.d(LOG_TAG, "Uri err: " + err_msg); } } private void callEmail(String emailbox){
if(TextUtils.isEmpty(emailbox)) return; final String prefix = "mailto:"; try { if(!emailbox.startsWith(prefix)) emailbox = prefix + emailbox; Uri uri = Uri.parse(emailbox); Intent intent = new Intent(Intent.ACTION_SENDTO, uri); mContext.startActivity(intent); } catch (Exception e) { String err_msg = e.getMessage(); Log.d(LOG_TAG, "Uri err: " + err_msg); } } public android.view.View.OnClickListener myOnClickListener = new android.view.View.OnClickListener() { @Override public void onClick(View v) { try { int id = v.getId(); int position = id-VIEW_INDEX; if(position <0 || position > mKeys.length) return; final String key = mKeys[position]; final String title = mTitles[position]; final String val = mVals[position]; if("website".equals(key)) { callBrowser(val); } else if("email".equals(key)) { callEmail(val); } } catch (Exception e) { // Do nothing! } } }; } 相关的layout文件部分如下:
<TextView android:id="@+id/detail_developer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/lbl_title_developer" android:textStyle="bold" android:background="#008F00" > </TextView> <com.xxx.yyy.LinearLayoutForListView android:id="@+id/detail_lst_web_email" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:visibility="visible" android:clickable="true" > </com.xxx.yyy.LinearLayoutForListView> 以下代码向这个假的ListView填入数据:
com.xxx.yyy.LinearLayoutForListView lst_developer = (com.xxx.yyy.LinearLayoutForListView) findViewById(R.id.detail_lst_web_email); String keys[]={ "website", "email"}; String titles[]={getResources().getString(R.string.lbl_title_developer_website), getResources().getString(R.string.lbl_title_developer_email)}; String vals[]={"http://", "abc@def.com"}; DeveloperInfoAdapter developerAdapter = new DeveloperInfoAdapter(this, keys, titles, vals); lst_developer.setOnclickLinstener(developerAdapter.myOnClickListener); lst_developer.setAdapter(developerAdapter); |
|