现在的位置: 首页 > 综合 > 正文

android 解决ScrollView与ListView的冲突(TableLayout+ScrollView)

2013年09月04日 ⁄ 综合 ⁄ 共 3811字 ⁄ 字号 评论关闭

     首先对于ScrollView和ListView这两个控件发生冲突我就不过多解释了,用过的同学们都知道,

     问题:ListView在ScrollView显示一行半,解决方法:http://jackxlee.blog.51cto.com/2493058/666475 这里有解决办法.不过实现后会发现,效果不是很友好,首先由别的界面跳转至该界面的时候,listview显示的不正常,

      第一:显示顺序不对。第二:scrollView显示不再最上面,而是现在在listview的中间,这点肯定不被认可.解决办法:scrollTo(0,0);不过这个方法必须要用handler实现:

mHandler.post(new Runnable() {   

@Override   
public void run() {   
((ScrollView)findViewById(R.id.main_sv)).scrollTo(10, 10) ;
}   
});

实现后结果会发现:在listview 初始化完以后,屏幕会一闪,其实就是由listview 的中间再次scrollTo顶部。效果很不友好.

本人正在开发新浪微博一些应用,新浪微博的评论列表显示的时候根本没有遇到上述情况,也许是自己比较笨吧,不知道该怎么实现,不过之前做过简单的动态Taable的应用,想想就一个一个生成吧,麻烦也好,起码可以实现.

下面是代码片段:

public void tableList(Context context, ArrayList<BlogInfo> blogInfos) {

		TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(
				android.widget.TableRow.LayoutParams.FILL_PARENT,
				android.widget.TableRow.LayoutParams.FILL_PARENT);
		AsyncImageLoader asyncImageLoader = new AsyncImageLoader();
		View convertView = null;
		for (int i = 0; i < blogInfos.size(); i++) {
			TableRow tableRow = new TableRow(context);
			final ViewHolder holder = new ViewHolder();

			convertView = LayoutInflater.from(context).inflate(
					R.layout.blogdetail_item, null);
			holder.imageLog = (ImageView) convertView
					.findViewById(R.id.iv_blogdetail_item);
			holder.textName = (TextView) convertView
					.findViewById(R.id.tv_blogtetail_item_name);
			holder.textComment = (TextView) convertView
					.findViewById(R.id.tv_blogdetail_item_content);
			holder.textTime = (TextView) convertView
					.findViewById(R.id.tv_blogdetail_item_time);

			holder.textName.setText(blogInfos.get(i).Title);
			holder.textComment.setText(blogInfos.get(i).Content);
			holder.textTime
					.setText(MyUtil.convertTime(blogInfos.get(i).Time, 1));

			Drawable drawable = asyncImageLoader.loadDrawable(
					blogInfos.get(i).LogImage, new ImageCallback() {
						@Override
						public void imageLoaded(Drawable imageDrawable,
								String imageUrl) {
							if (imageDrawable != null) {
								holder.imageLog.setImageDrawable(imageDrawable);
							} else {
								holder.imageLog
										.setImageResource(R.drawable.u6_normal);
							}

						}
					});
			if (drawable != null) {
				holder.imageLog.setImageDrawable(drawable);
			}

			tableRow.addView(convertView, layoutParams);
			tb_blogdetail.addView(tableRow);
		}

	}

       其实很简单,就是创建了一个View作为TableRow,把数据一个一个的填充进去,获取有些同学会发现这个效率很低,早N年前google就提出来了要创建一个类ViewHolder,用于减少findbyId的使用,可是我一用就报错,错误信息如下:

The specified child already has a parent. You must call removeView() on the child's parent first.

   这个应该可以提高性能,本人水平有限,知道的朋友麻烦解释下.

  下面效果如图:

       
  

      Listview 加载中...                  Listview加载完毕.                  下拉Listview.

  TableLayout+ScrollView 很好的解决了Listview和ScrollView之间的冲突.虽说我写的性能不高,但是显示这些内容足够了,效果如同新浪微博一样,呵呵,就说这么多了。有什么不足之处,或更好的解决方案:请您留吉言.




方法二:(动态修改ListView的高度,切记:在使用ScrollView嵌套ListView布局的时候,中间一定要加一个LinearLayout或者什么的布局,不然效果出不来,原因不明,总之知道如何就OK了.

例如:

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" >

      <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:padding="20dp" >

            <com.jj.corner.MyListView
                android:id="@+id/mylistview_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="20dp"
                android:layout_marginTop="20dp"
                android:background="@drawable/list_default_round"
                android:cacheColorHint="#00000000" />
        </LinearLayout>
    </ScrollView>

动态修改ListView高度方法:

/***
	 * 动态设置listview的高度
	 * 
	 * @param listView
	 */
	public void setListViewHeightBasedOnChildren(ListView listView) {
		ListAdapter listAdapter = listView.getAdapter();
		if (listAdapter == null) {
			return;
		}
		int totalHeight = 0;
		for (int i = 0; i < listAdapter.getCount(); i++) {
			View listItem = listAdapter.getView(i, null, listView);
			listItem.measure(0, 0);
			totalHeight += listItem.getMeasuredHeight();
		}
		ViewGroup.LayoutParams params = listView.getLayoutParams();
		params.height = totalHeight
				+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
		// params.height += 5;// if without this statement,the listview will be
		// a
		// little short
		// listView.getDividerHeight()获取子项间分隔符占用的高度
		// params.height最后得到整个ListView完整显示需要的高度
		listView.setLayoutParams(params);
	}


      



          

抱歉!评论已关闭.