解决嵌套在ScrollView的GridView Item高度不一致时高度不自适应

从1月8号开始就纠结,嵌套在ScrollView中的GridView,若是其Item高度不一致,导致GridView Item之间重叠,并且显示不全的问题。。。(ps:因为这个问题,眼睛一直盯着屏幕患了眼睑炎,内麦粒肿,而且还便秘,估计内里的火?反应到眼睛上了,cry)不过最后被老大轻轻松松给搞定,无地自容的赶脚。。。

首先讲一下为了解决这个问题尝试了哪些法子:

遇到这个问题在修改xml布局的一些属性无果后果然百度,百度的结果不尽人意啊,没有多少合适的,果断奔向Google,借用同事的VPN去stackoverflow查看相关问题,真的有哦,国外大神们post了一些解决方案,例如重写GridView禁止滑动,这个我也写了,还有就是重写Item的根布局RelativeLayout,在那里获取Item的高度,动态计算,始终觉得这个问题不是大问题只是很恶心而已没必要太大动干戈,so未采用那位大神的重写控件的方案。那剩下的就是在Adapter的getView方法中动态设置Item的高度,具体代码如下:

setHeight()方法详细如下图

按照上述方法依然没什么卵用啊,另外,在Activity中拿到Item的最大高度动态给GridView设置上,也是没有效果的;若是在Item的xml中写死一个够大的高度,GridView就会自动扩展了,这说明在public View getView(int position, View convertView, ViewGroup parent) 方法中,参数parent在初始化第一次的时候就必须拿到一个高度,否则GridView会始终默认最初的高而不扩展。理解parent的意义!!!parent是GridView的根布局

其实一直没解决这个问题主要是太纠结GridView的使用,想过使用其他控件代替,但是因在eclipse下开发,除了GridView其他的就是使用LinearLayout动态添加布局了(因Eclipse下RecyclerView没有最新的库,很多效果大打折扣,还有其他各种插件的使用,哎,抓紧换到Android Studio吧)考虑到使用LinearLayout,切换选中状态没有GridView的notifyDataSetChanged()灵活,迟迟不敢下手啊。

下面是老大灵活解决这个问题的方案:

自定义一个LinearLayout,在代码中编写一个标签的内容,供外部灵活调用改变数据及UI的接口,把代码po出来:

item_activity_tag_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content" >

    <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content" >

        <RelativeLayout

            android:id="@+id/rl_tag_layout"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginBottom="5dp"

            android:layout_marginLeft="6dp"

            android:layout_marginRight="6dp"

            android:layout_marginTop="5dp"

            android:background="@drawable/yuanjiao_blue_rect_line" >

            <TextView

                android:id="@+id/txt_title"

                style="@style/item_txt_middle"

                android:layout_centerInParent="true"

                android:ellipsize="end"

                android:gravity="center"

                android:maxLines="4"

                android:padding="3dp"

                android:singleLine="false"

                android:textColor="@color/activity_tag_color" />

       

        <ImageView

            android:id="@+id/img_selected"

            android:layout_width="15dp"

            android:layout_height="15dp"

            android:layout_alignBottom="@id/rl_tag_layout"

            android:layout_alignParentRight="true"

            android:src="@drawable/icon_select_check"

            android:visibility="visible" />

   

自定义ActivityTagLayout.java

public class ActivityTagLayout extends LinearLayout {

private Context context;

private LayoutInflater mInflater;

private RelativeLayout tagLayout;

private TextView mTitle;

private ImageView mSelectImg;

public ActivityTagLayout(Context context) {

super(context);

this.context = context;

mInflater = LayoutInflater.from(context);

initView();

}

private void initView() {

View view = mInflater.inflate(R.layout.item_activity_tag_layout, null);

tagLayout = (RelativeLayout) view.findViewById(R.id.rl_tag_layout);

mTitle = (TextView) view.findViewById(R.id.txt_title);

mSelectImg = (ImageView) view.findViewById(R.id.img_selected);

this.addView(view);

}

/**

  • 给当前Layout设置数据

  • @param bean

*/

public void setData(ActivityTagBean bean) {

mTitle.setText(bean.name);

if (bean.isSelected) {

mSelectImg.setVisibility(View.VISIBLE);

tagLayout.setBackgroundResource(R.drawable.yuanjiao_blue_rect_bg);

mTitle.setTextColor(context.getResources().getColor(

R.color.WhiteColor));

} else {

mSelectImg.setVisibility(View.GONE);

tagLayout.setBackgroundResource(R.drawable.yuanjiao_blue_rect_line);

mTitle.setTextColor(context.getResources().getColor(

R.color.activity_tag_color));

}

}

/**

  • 根据是否选中刷新UI

  • @param isSelected

*/

public void resetTagSelect(boolean isSelected) {

if (isSelected) {

mSelectImg.setVisibility(View.VISIBLE);

tagLayout.setBackgroundResource(R.drawable.yuanjiao_blue_rect_bg);

mTitle.setTextColor(context.getResources().getColor(

R.color.WhiteColor));

} else {

mSelectImg.setVisibility(View.GONE);

tagLayout.setBackgroundResource(R.drawable.yuanjiao_blue_rect_line);

mTitle.setTextColor(context.getResources().getColor(

R.color.activity_tag_color));

}

}

}

在Activity中,有个LinearLayout容器用于添加标签:tagContainer,在获取数据的接口下调用下面的方法;

activityTagBeans为数据集合(ArrayList),因要求布局每行3列,根据总数计算所需行数

private void setActivityTagDatas() {

    tagContainer.removeAllViews();

    int row = 0;// 计算需要行数

    if ((activityTagBeans.size() % 3) == 0) {

    row = activityTagBeans.size() / 3;

    } else {

    row = (activityTagBeans.size() / 3) + 1;

    }

    

    for (int i = 0; i < row; i++) {

    LinearLayout rowLayout = new LinearLayout(context);

    rowLayout.setOrientation(LinearLayout.HORIZONTAL);

    rowLayout.setWeightSum(3);

    

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

    LinearLayout.LayoutParams.MATCH_PARENT,

    LinearLayout.LayoutParams.WRAP_CONTENT);

    

    rowLayout.setLayoutParams(params);

    

    addActivityTag(i, rowLayout);

    

    tagContainer.addView(rowLayout);

    }

}

/**

  • 添加每行数据

  • @param row 行

  • @param layout

*/

private void addActivityTag(int row, LinearLayout layout) {

for (int i = 0; i < 3; i++) {

final int position = (row * 3 + i);

if (position < activityTagBeans.size()) {

ActivityTagLayout tagLayout = new ActivityTagLayout(this);

                                // params中的width置为0,这样才能保证跟布局weightSum=3起作用

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

0, LinearLayout.LayoutParams.WRAP_CONTENT);

params.weight = 1;// 此处weight必须置为1

params.bottomMargin = 10;

tagLayout.setData(activityTagBeans.get(position));

tagLayout.setLayoutParams(params);

tagLayout.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

StatisticsUtil.customEvent(PageSettings.ACTIVITY_RELEASE_NEW_DYNAMIC,

String.format(getString(R.string.dynamic_release_activity_choose_click), activityTagBeans.get(position).name));

activityTagBeans.get(position).isSelected = !activityTagBeans.get(position).isSelected;

if (lastTagPosition != -1 && lastTagPosition != position) {

activityTagBeans.get(lastTagPosition).isSelected = false;

}

resetTagSelected(position);

if (activityTagBeans.get(position).isSelected) {

if (tvActivityDesc.getVisibility() == View.INVISIBLE) {

tvActivityDesc.setVisibility(View.VISIBLE);

}

activityId = activityTagBeans.get(position).activityId;

if (J_CommonUtils.isEmpty(activityTagBeans.get(position).desc)

&& !J_CommonUtils.isEmpty(activityTagBeans.get(position).showTime)) {

tvActivityDesc.setText(activityTagBeans.get(position).showTime);

} else if (!J_CommonUtils.isEmpty(activityTagBeans.get(position).desc)

&& J_CommonUtils.isEmpty(activityTagBeans.get(position).showTime)) {

tvActivityDesc.setText(activityTagBeans.get(position).desc);

} else if (!J_CommonUtils.isEmpty(activityTagBeans.get(position).desc)

&& !J_CommonUtils.isEmpty(activityTagBeans.get(position).showTime)) {

tvActivityDesc.setText(activityTagBeans.get(position).desc + "nn"

+ activityTagBeans.get(position).showTime);

} else {

tvActivityDesc.setVisibility(View.INVISIBLE);

}

} else {

activityId = "";

tvActivityDesc.setVisibility(View.INVISIBLE);

}

lastTagPosition = position;

if (!isBottom) {

J_Application.handler.post(new Runnable() {

    @Override

    public void run() {

        scrollView.fullScroll(ScrollView.FOCUS_DOWN);

        isBottom = true;

    }

});

}

}

});

layout.addView(tagLayout);

}

}

}

/**

  • 重置选中状态

*/

private void resetTagSelected(final int selectIndex) {

for (int i = 0; i < tagContainer.getChildCount(); i++) {

LinearLayout rowLayout = (LinearLayout) tagContainer.getChildAt(i);

for (int k = 0; k < rowLayout.getChildCount(); k++) {

final ActivityTagLayout tagLayout = (ActivityTagLayout) rowLayout

.getChildAt(k);

if ((i * 3 + k) == selectIndex) {

tagLayout.resetTagSelect(activityTagBeans.get(selectIndex).isSelected);

} else {

tagLayout.resetTagSelect(false);// 根据重写的Layout灵活修改选中状态

}

}

}

}

最终效果图如下:

13.png

改变状态充分利用tagContainer.getChildAt(i)获取每个子Item!!!这点我竟然没想到,哎,思维太局限了!!!以此谨记