问题描述:在一个页面中,最外层的根布局为ScrollView,里面嵌套着GridView,但是GridView并不是在整个布局的最顶端,而是布局到了整个页面的底部,在GridView上面还布局着其他控件,但是当整个页面的数据加载完成以后,页面的初始布局并非显示页面的顶部位置,而是自动滚动到了页面的底部。
布局代码:
<?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="match_parent"
android:background="@color/app_bg"
android:orientation="vertical" >
<ScrollView
android:id="@+id/scSpace"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/shadow_title" />
<!-- !!!!!!!!!!ScrollView嵌套GridView或者ListView的问题:整个界面的数据加载完成以后,自动滚动到了这里了!!!!!!!!!!。解决办法:使得界面最顶部的一个控件获得焦点,滚动条自然就到顶部去了 -->
<ListView
android:id="@+id/listview_personalhealthindex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/app_bg" >
</ListView>
</LinearLayout>
</ScrollView>
</LinearLayout>
解决办法一:
我大概是和你遇见了同样的问题,你可以灵活处理一下,不要去管那个滚动条的位置了,我试过了,用scrollViewMsg.scrollTo(0,0);一点效果没有。
因为我的scrollView里面ListView的上面还有其他的控件,所以我想到一个办法就是使得一开始的时候就让上面其中一个控件获得焦点,滚动条自然就到顶部去了,如下:
txtBaseMsg.setFocusable(true);
txtBaseMsg.setFocusableInTouchMode(true);
txtBaseMsg.requestFocus();
这样的布局会导致ListView显示不全,问题相当棘手,好在万能的网友给出了答案
滚动的解决办法1:在
listView.setAdapter(indexAdapter);
后面加入如下方法:
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);
}
即可解决,但是这样会造成一个小的问题打开该界面时,会显示到底部而不是从顶部显示
滚动的解决办法2:
实现原理 重写onMeasure代码,停用GridView的滚动功能
这里以GridView为例,重写GridView,布局代码如下:ListView同样的原理
<com.example.ui.MyGridView
android:id="@+id/healthhomereson_gv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="@dimen/margin_medium"
android:background="@color/white"
android:descendantFocusability="blocksDescendants"
android:numColumns="3" >
</com.example.ui.MyGridView>
重写GridView代码如下:
package com.example.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
public class MyGridView extends GridView {
public MyGridView(Context context) {
super(context);
}
public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//该自定义控件只是重写了GridView的onMeasure方法,使其不会出现滚动条,ScrollView嵌套ListView也是同样的道理,不再赘述。
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
现实顶部的解决办法1:初始化的时候就让该界面的顶部的某一个控件获得焦点,滚动条自然就显示到顶部了,代码如下:
txtBaseMsg.setFocusable(true);
txtBaseMsg.setFocusableInTouchMode(true);
txtBaseMsg.requestFocus();
现实顶部的解决办法2
:在加入setListViewHeightBasedOnChildren(listView);的后面我们加入如下代码:
listview.post(new Runnable() {
@Override
public void run() {
((ScrollView)findViewById(R.id.scSpace)).scrollTo(0, 0);
}
});
同样也可完美解决,注:scSpace是ScorollView的id
参考链接:
http://www.csdn123.com/html/exception/645/645764_645754_645761.htm
http://blog.csdn.net/hitlion2008/article/details/6737459
http://bbs.csdn.net/topics/370109727
http://blog.csdn.net/lonely_fireworks/article/details/7242544