本帖最后由 terryyhl 于 2010-8-13 15:19 编辑
ListView 与 ScrollView 同在一个界面用头脑想想都觉得不大可能这样做,但还真的有美工这样做了,有点郁闷~!!沟通无果,解决之~~~~!初期还真没啥头绪,Google 一下看到有很多同样碰到这类头痛的问题,不好意思还没描述问题症状。ListView 与 ScrollView 同在一界面会导致ListView 显示变形,因为ListView 也有自带的滚动事件,故无法与ScrollView 相容,可能造成的现象是ListView 只能显示一行或者两行,其他数据在那一点儿宽的地方做滚动,甚不雅观。 下面是我的一个实现 步骤:
- 1、继承LinearLayout,既然会冲突那就不用ListView 改成线性布局做动态布局效果
- 2、继承BaseAdapter ,可以参照一下Android app源码中 Widget 目录下的SimpleAdapter 为前面扩展的LinearLayout做数据。
- 3、模拟数据填充扩展后的BaseAdapter 为扩展后的LinearLayout 加载数据
第一步:新建LinearLayoutForListView 类使其扩展LinearLayout重写以下两个方法: public LinearLayoutForListView(Context context) { super(context);
}
public LinearLayoutForListView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub
}
这两个方法可选,不过建议都写上,第一个方法可以让我们通过 编程的方式 实例化出来,第二个方法可以允许我们通过 XML的方式注册 控件,可以在第二个方法里面为扩展的复合组件加属性,详细使用方法请点击这里 。 为其添加get / set 方法 /** * 获取Adapter * * @return adapter */ public AdapterForLinearLayout getAdpater() { return adapter; }
/** * 设置数据 * * @param adpater */ public void setAdapter(AdapterForLinearLayout adpater) { this.adapter = adpater; bindLinearLayout(); }
/** * 获取点击事件 * * @return */ public OnClickListener getOnclickListner() { return onClickListener; }
/** * 设置点击事件 * * @param onClickListener */ public void setOnclickLinstener(OnClickListener onClickListener) { this.onClickListener = onClickListener; }
第二步:新建AdapterForLinearLayout 类继承自BaseAdapter,并为其添加构造函数 private LayoutInflater mInflater; private int resource; private List<? extends Map<String, ?>> data; private String[] from; private int[] to;
public AdapterForLinearLayout(Context context, List<? extends Map<String, ?>> data, int resouce, String[] from, int[] to) { this.data = data; this.resource = resouce; this.data = data; this.from = from; this.to = to; this.mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
此构造函数模仿 simpleAdapter 通过传进来的resouce 为布局设置数据。通过继承BaseAdapter 重要的实现方法在下面getView ,此方法判断通过传进来的 String[] from 与 int[] to 为分别查找出View 并为View 设置相应的Text,代码如下: @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub
convertView = mInflater.inflate(resource, null); Map<String, ?> item = data.get(position); int count = to.length; for (int i = 0; i < count; i++) { View v = convertView.findViewById(to); bindView(v, item, from); } convertView.setTag(position); return convertView; }
/** * 绑定视图 * @param view * @param item * @param from */ private void bindView(View view, Map<String, ?> item, String from) { Object data = item.get(from); if (view instanceof TextView) { ((TextView) view).setText(data == null ? "" : data.toString()); } }
Tip:
- BindView 方法是一个自定义方法,在方法体内可以为通过判断使本类更具灵活性,如上,你不仅可以判断是TextView 并且可以传入任何你想要的View 只要在方法体内加入相应判断即可,数据可以通过data 做相应处理,具体如何操作读者可另行测试。
- convertView.setTag(position); 此句代码为View 设置tag 在以后我们可以通过 getTag 找出下标,后文有介绍如何通过下标操作数据。
下面是两个类的全部代码,读者可以无须更改直接使用: LinearLayoutForListViewpackage com.terry.widget;
import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.LinearLayout;
public class LinearLayoutForListView extends LinearLayout {
private AdapterForLinearLayout adapter; private OnClickListener onClickListener = null;
/** * 绑定布局 */ public void bindLinearLayout() { int count = adapter.getCount(); for (int i = 0; i < count; i++) { View v = adapter.getView(i, null, null);
v.setOnClickListener(this.onClickListener); if (i == count - 1) { LinearLayout ly = (LinearLayout) v; ly.removeViewAt(2); } 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 AdapterForLinearLayout getAdpater() { return adapter; }
/** * 设置数据 * * @param adpater */ public void setAdapter(AdapterForLinearLayout adpater) { this.adapter = adpater; bindLinearLayout(); }
/** * 获取点击事件 * * @return */ public OnClickListener getOnclickListner() { return onClickListener; }
/** * 设置点击事件 * * @param onClickListener */ public void setOnclickLinstener(OnClickListener onClickListener) { this.onClickListener = onClickListener; }
}
AdapterForLinearLayoutpackage com.terry.widget;
import java.util.List; import java.util.Map;
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView;
public class AdapterForLinearLayout extends BaseAdapter {
private LayoutInflater mInflater; private int resource; private List<? extends Map<String, ?>> data; private String[] from; private int[] to;
public AdapterForLinearLayout(Context context, List<? extends Map<String, ?>> data, int resouce, String[] from, int[] to) { this.data = data; this.resource = resouce; this.data = data; this.from = from; this.to = to; this.mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
@Override public int getCount() { // TODO Auto-generated method stub
return data.size(); }
@Override public Object getItem(int position) { // TODO Auto-generated method stub
return data.get(position); }
@SuppressWarnings("unchecked") public String get(int position, Object key) { Map<String, ?> map = (Map<String, ?>) getItem(position); return map.get(key).toString(); }
@Override public long getItemId(int position) { // TODO Auto-generated method stub
return position; }
@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub
convertView = mInflater.inflate(resource, null); Map<String, ?> item = data.get(position); int count = to.length; for (int i = 0; i < count; i++) { View v = convertView.findViewById(to); bindView(v, item, from); } convertView.setTag(position); return convertView; }
/** * 绑定视图 * @param view * @param item * @param from */ private void bindView(View view, Map<String, ?> item, String from) { Object data = item.get(from); if (view instanceof TextView) { ((TextView) view).setText(data == null ? "" : data.toString()); } } }
对应的XML 如下: <?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" androidrientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/TextView01" android:layout_marginLeft="10px" android:textAppearance="?android:attr/textAppearanceLarge" android:layout_width="wrap_content" android:layout_height="wrap_content"> </TextView> <TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:layout_marginLeft="10px" android:layout_height="wrap_content"> </TextView> <View android:layout_height="1px" android:background="#FFFFFF" android:layout_width="fill_parent"></View> </LinearLayout>
第三步:主页面使用控件并为其设置数据
- XML如下:
<com.terry.widget.LinearLayoutForListView androidrientation="vertical" android:layout_width="450px" android:layout_height="fill_parent" android:id="@+id/ListView01"> </com.terry.widget.LinearLayoutForListView>
- 加载数据如下:
lv = (LinearLayoutForListView) findViewById(R.id.ListView01); for (int i = 0; i < 10; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("key_name", "name" + i); map.put("value_name", "value" + i); list.add(map); }
final AdapterForLinearLayout Layoutadpater = new AdapterForLinearLayout( this, list, R.layout.test, new String[] { "key_name", "value_name" }, new int[] { R.id.TextView01, R.id.TextView02 });
- 事件操作,并通过下标得到数据源:
lv.setOnclickLinstener(new OnClickListener() {
@Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText( BlueToothActivity.this, Layoutadpater.get(Integer.parseInt(v.getTag() .toString()), "key_name"), 1000).show(); } }); lv.setAdapter(Layoutadpater);
Tip:get方法是在Layoutadpater 封装的一个通过下标获取相应数据的方法请参考上文。
至此完成。有碰到这个问题的朋友可以试试。
|
相关推荐
http://blog.csdn.net/wishes222/article/details/9970805
完美解决listView嵌套scrollView的滑动冲突问题
本Demo主要是用于解决ListView和ScrollView嵌套冲突给ListView带来显示不正常的问题,通过动态测量ListVIew高度来解决
自定义的ViewPager,可以实现页面之前的相互切换,可以...同时该ViewPager解决了传统ViewPager和ListView,ScrollView滑动冲突问题,当然ListView的滑动冲突实在ScrollView中解决的。实践表明,滑动切换效果较好。
自定义的一个ListView,在布局的时候使用,可以解决ListView和ScrollView冲突问题
android ListView和ScrollView事件冲突的解决方法
解决listview和scrollview冲突 使用linearlayout自定一个listview 用法与listview相同
listview与scrollview冲突问题解决
在一些项目中需要用到listview嵌套在scrollview中的情况,但会碰到焦点冲突,scrollview焦点覆盖listview造成listview不能滑动,这种情况时要在scrollview中添加android:fillViewport="true"这句,并在listview中...
Listview与Scrollview冲突的问题
Android_ScrollView与ListView_GridView共存冲突解决方案
android 解决ScrollView和listView嵌套冲突问题(保证在ScrollView中滑动listView只响应listView的滑动)
代码里面有详细的注释,肯定能看懂,如果还想了解原理或者具体接过程看同步博文http://blog.csdn.net/qq_28690547/article/details/50397106
Android listview viewpager 滑动 跳动 冲突解决 ListView中嵌套ViewPage有或者滑动手势冲突解决 blog 地址 : http://blog.csdn.net/aaawqqq/article/details/43824631
本Demo展示如何在ScrollView中嵌套ListView,通过自定义ListView有效解决冲突问题
很多朋友因项目需求问题需要在ScrollView中嵌套使用ListView或ScrollView 但是彼此的滑动事件会发生冲突,网上大多数都是计算ListView的高度来解决这个问题,但个人亲手尝试 结果ListView的Item要是过多的话ListView...
在Android应用程序开发中,我们经常用到ListView这个控件,可能大家会对方方正正的ListView控件感到厌烦,这里来实现圆角的ListView,并放在ScrollView控件中
使用BaseAdapter自定义适配器,采用了回收converView和ViewHolder优化代码,并且解决了在ListView中使用Button时,ListView的itemClick不能被触发的问题。
用于解决scrollview组件嵌套listview组件时候 两者之间的冲突问题