当前位置: 首页 >> 开发 >> Android >> 阅读正文

解决Android ListView 和 ScrollView 共存时冲突 问题 方法其一

2013年11月20日     分类:Android     3,709 次浏览
    5 条评论     发表评论  

当同一个页面布局中的ScrollView中包含有ListView时,两个布局由于都有滑动而导致冲突,最明显的特征就是当ListView中有多个子项时,会出现显示不全的情况,只会显示一两个子项。

以前查到一个简单的解决办法setListViewHeightBasedOnChildren(ListView listView)的那个办法,是测出ListView中每一个子项视图的高度,然后再相加起来,以这个值来设定整个ListView的高度。这种方法的优点是比较简单,能解决子项视图布局比较简单且文字较少的情况;但不足之处是每次刷新ListView时都要调用这个函数来重新设定ListView的高度,重点是:若子项视图中文字过多,出现文字自动换行的时候,此时测出来的高度就不准确了,难以做到准确设置ListView的高度。

这次要介绍的方法虽说有点麻烦,但是相对来说比较治本的方法,其思想是继承并扩展线性布局LinearLayout,用LinearLayout替代ListView来实现ListView的功能和效果。

下面是效果示例:

这是修改前的冲突情况(ListView显示只能显示第一行)

listview修改前

 

listview修改后的效果

listview修改后的效果

 

 

package com.and.mine;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;

public class LinearLayoutForListView extends LinearLayout
{
	private BaseAdapter adapter;
	private OnItemClickListener onItemClickListener;

	/**
	 * 通过 Java代码  实例化
	 * @param context
	 */
	public LinearLayoutForListView(Context context)
	{
		super(context);
		//设置LinearLayoutForListView为垂直布局,否者默认为水平布局,容易疏忽导致子项显示不全
		LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
	}

	/**
	 * 此构造函数可以允许我们通过 XML的方式注册 控件
	 * @param context
	 * @param attrs
	 */
	public LinearLayoutForListView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
	}

	/**
	 * 设置适配器
	 * 
	 * @param adpater
	 */
	public void setAdapter(BaseAdapter adpater)
	{
		this.adapter = adpater;
		bindLinearLayout();
	}

	/**
	 * 获取适配器Adapter
	 * 
	 * @return adapter
	 */
	public BaseAdapter getAdpater()
	{
		return adapter;
	}

	/**
	 * 绑定布局:将每个子项的视图view添加进此线性布局LinearLayout中
	 */
	public void bindLinearLayout()
	{
		int count = adapter.getCount();
		for (int i = 0; i < count; i++)
		{
			View v = adapter.getView(i, null, null);

			if (i != count - 1)
			{	//添加每项item之间的分割线
				 v = addLine(v);
			}
			addView(v, i);
		}
		setItemClickListener();
		Log.v("countTAG", "" + count);
	}

	/**
	 * 添加每项item之间的分割线
	 * 
	 * @param view
	 * @return
	 */
	public View addLine(View view)
	{
		//分割线view
		View lineView = new View(view.getContext());

		// 将数据从dip(即dp)转换到px,第一参数为数据原单位(此为DIP),第二参数为要转换的数据值
		float fPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				(float) 0.5, view.getResources().getDisplayMetrics());
		int iPx = Math.round(fPx);

		LayoutParams layoutParams = new LayoutParams(
				LinearLayout.LayoutParams.MATCH_PARENT, iPx);
		lineView.setLayoutParams(layoutParams);
		lineView.setBackgroundColor(view.getSolidColor());

		LinearLayout ly = new LinearLayout(view.getContext());
		ly.setOrientation(LinearLayout.VERTICAL);

		ly.addView(view);
		ly.addView(lineView);

		return ly;
	}

	/**
	 * 设置点击子项事件监听对象
	 * @param onItemClickListener
	 */
	public void setOnItemClickListener(OnItemClickListener onItemClickListener)
	{
		this.onItemClickListener = onItemClickListener;
		setItemClickListener();
	}

	/**
	 * 获取点击子项事件监听对象
	 * @return
	 */
	public OnItemClickListener getOnItemClickListener()
	{
		return onItemClickListener;
	}

	/**
	 * 设置子项点击事件
	 */
	private void setItemClickListener()
	{
		if (adapter != null)
		{
			for (int i = 0; i < LinearLayoutForListView.this.getChildCount(); i++)
			{
				View view = LinearLayoutForListView.this.getChildAt(i);
				if (onItemClickListener != null)
				{
					//设置子项点击事件
					view.setOnClickListener(new ItemClickListener(view, i, adapter.getItemId(i)));
				}
			}
		}
	}

	class ItemClickListener implements OnClickListener
	{
		View view;
		int position;
		long id;

		public ItemClickListener(View view, int position, long id)
		{
			this.view = view;
			this.position = position;
			this.id = id;
		}

		@Override
		public void onClick(View v)
		{
			//将子项视图的点击事件转发到整个listview的OnItemClick事件中
			//此方法有局限性,第一个参数 AdapterView<?> parent(即当前listView的视图)没传入onItemClick()中
			onItemClickListener.onItemClick(null, view, position, id);
		}
	}
}

 

 

在XML中使用自定义控件来调用LinearLayoutForListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <com.and.mine.LinearLayoutForListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </com.and.mine.LinearLayoutForListView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="使用方法" />

</LinearLayout>

当然这种这种方法也是存在不足之处的,欢迎各位指正

THE END

分享到

相关文章

评论列表

  • 无意乃佳
       

    测试啦啦,跳动的小肥皂!!!

  • 无意乃佳
       

    不错嘛

  • AND
       

    试试评论~

    • Orange
         

      test~

    • ABC
         

      test too

发表评论