总结ScrollView中嵌套ListView/GridView的方法
一、ScrollView中嵌套ListView/GridView:
方法一:计算ListView的高度
public static void setListViewHeightBasedOnChildren(ListView listView) {ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
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));
listView.setLayoutParams(params);
}
处理方式:在将楼上这个方法拷贝到工具类中,在ListVIew.setAdapter 的下方调用这个方法即可,如下所示:
apprAdapter = new ApprovedPersonAdapter(mContext, mListAped);mListView.setAdapter(apprAdapter);
ListHeightUtils.setListViewHeightBasedOnChildren(mListView);
方法二:重写ListView/GridView
重写ListView:
public class MyScrollVListView extends ListView {
public MyScrollVListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyScrollVListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollVListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
重写GridView:
public class MyScrollGridView extends GridView {private boolean haveScrollbar = false;
public MyScrollGridView(Context context) {
super(context);
}
public MyScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 设置是否有ScrollBar,当要在ScollView中显示时,应当设置为false。 默认为 true
*
* @param haveScrollbars
*/
public void setHaveScrollbar(boolean haveScrollbar) {
this.haveScrollbar = haveScrollbar;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
处理方式:和正常的布局ListView/GridView一样,只是这里需要用全路径,即可解决,如下所示:
<com.derek.views.MyScrollVListViewandroid:id="@+id/mListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</com.derek.views.MyScrollVListView>
方法三:LinerLayout代替ListView/GridView
1、先在需要布局ListView/GridView的地方布局上一个LinerLayout,如下所示:
<LinearLayout
android:id="@+id/mLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:adjustViewBounds="true"
android:background="#85808c"
android:orientation="vertical" >
</LinearLayout>
2、在FindViewById该对象,如下所示:
mLinearLayout= (LinearLayout) findViewById(R.id.mLinearLayout);3、初始化数据
/**
* 动态添加数据
* @param jSONArrayOps
*/
private void initGridView(JSONArray jSONArrayOps) {
mLinearLayout.removeAllViews();
ArrayList<HashMap<String, Object>> lstItem = getOptionData();
SimpleAdapter saImageAdapter = new SimpleAdapter(mContext,
lstItem,// 数据源
R.layout.item_gridview_button,// 显示布局
new String[] {"itemText" },
new int[] { R.id.mBtnItemText });
mGridViewButton = new SquareGridView(mContext);
mGridViewButton.setAdapter(saImageAdapter);
int size = JSONArrayOps.length();
int numColumns = 0;
if (size%2 == 0) {
numColumns = 2;
}else if(size%3 == 0){
numColumns = 3;
}else{
numColumns = 2;
}
mGridViewButton.setNumColumns(numColumns);
//mGridViewButton.setColumnWidth(120);
mGridViewButton.setGravity(Gravity.CENTER);
mGridViewButton.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
//去掉点击效果的背景
mGridViewButton.setSelector(new ColorDrawable(Color.TRANSPARENT));
mGridViewButton.setVerticalSpacing(DensitydiUtil
.dip2px(mContext, 3));
int heigth = (int) getResources().getDimension(R.dimen.height_26_80);
if (size <= 2) {
mGridViewButton.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, heigth/2));
} else {
mGridViewButton.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, heigth));
}
/**监听事件**/
mGridViewButton.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String data = edtContent.getText().toString();
//***赋值的目的是为了点击拒绝时能促发后台修改数据**//*
if (TextUtils.isEmpty(data)) {
data = mContext.getResources().getString(R.string.strAppApproval);
}
try {
String mName = JSONArrayOps.getString(position);
requestApprovalData( mName,data);
Tools.printInfo(mName);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
// new LayoutParam(LayoutParam.FILL_PARENT, LayoutParam.FILL_PARENT)
mLinearLayout.addView(mGridViewButton);
}
如此将数据组装好后,该问题也基本解决了,mLinearLayout.removeAllViews();
表示先清空所有的View,便于每次添加进去的都是新的View。此方法在很多动态添加数据中都会用上,ListView的方法与此一样。
二、ScrollView嵌套ListView时,嵌套的布局是A布局+ListView+B布局的形式,当A布局中的内容超过一屏时,ListView的最后一个Item总是显示不全?
解决方案: (1)ListView不能用自定义的,必须用原生的ListView;
(2)ListView的宽高都用match_parent或fill_parent;
(3)用计算高度的方式去实现setListViewHeightBasedOnChildren(ListView);
(4)adapter的item的根布局必须为LinearLayout布局,不然计算高度时会有问题;
(5)ScrollView中添加属性android:fillViewport="true"
利用以上的5点,基本可以解决问题,我是这样解决,如果有没有解决的,请注意布局上看看有什么问题,把多余的功能去掉,从最基本的只显示ListView开始调节,一个功能一个功能的加上去,看看是哪里出问题,就逐步排除并解决。
ListView中嵌套ListView的处理在后续的文章中单独讲解,其实这三种方法网上也基本有的,只是便于android的学习记录一下这个过程。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。