我有一个ScrollView的问题,里面有一个个性化的GridView和其他视图。第一次启动Activity时,ScrollView从顶部开始,但是如果我访问Activity其他时候ScrollView启动在GridView的开头。我在this link中使用了我的GridView中的ExpandableHeightGridView类。 Activity布局的xml代码就是这个:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollViewLuogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff" >
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_marginLeft="14dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:adjustViewBounds="true"
android:maxHeight="200dp"
android:maxWidth="200dp"
android:scaleType="fitXY"
android:src="@android:drawable/ic_menu_gallery" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/nomeTVActivityLuogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="17sp"
android:textColor="#005788" />
<TextView
android:id="@+id/indirizzoTVActivityLuogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/linearLayout2"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageViewMappaLuogo"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="14dp"
android:layout_marginRight="14dp"
android:layout_marginTop="5dp"
android:scaleType="fitXY"
android:src="@drawable/sfondo_mappa" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:text="Immagini"
android:textColor="#97d6f9" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_marginLeft="14dp"
android:layout_marginRight="14dp"
android:layout_marginTop="5dp"
android:background="#97d6f9" />
<com.example.mappine.ExpandableHeightGridView
android:id="@+id/gridViewLuogo"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:numColumns="3" >
</com.example.mappine.ExpandableHeightGridView>
</LinearLayout>
</RelativeLayout>
我尝试过使用代码scrollView.fullScroll(ScrollView.FOCUS_UP);
,但它没有工作。即使scrollView.scrollTo(0, 0);
我也没有成功。
唯一有效的代码是:
scrollView.post(new Runnable()
{
public void run() {
scrollViewLuogo.fullScroll(ScrollView.FOCUS_UP);
}
});
但它会从GridView的顶部到屏幕顶部进行快速动画,我不喜欢它。
有什么建议吗?
答案 0 :(得分:165)
解决方案:
好的抱歉,如果这是一个迟到的回复,但我偶然发现同样的问题(只是我正在使用ListView)并且有一些试验和错误我找到了解决方案:< / p>
基本上问题在于,当你&#34; hack&#34;时,GridView / ListView子节点会自动请求父焦点(ScrollView)。并使用 ExpandableHeightGridView 调整其内容,这在渲染布局后发生,因此当您尝试使用scrollTo()向上滚动时会看到该动画(在创建布局后发生,并且在调整gridView后调整任何大小通用回调对于以编程方式处理它是没用的。)
那么,我找到的最简单的解决方案是简单地在ListView / GridView上禁用focusable属性:
listView.setFocusable(false);
当你第一次进入活动时,焦点将默认,而不是依赖于Listview / GridView。
所有工作正常=)
答案 1 :(得分:21)
最简单的方法是在父ScrollView上添加以下xml属性:
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
这意味着当您启动活动时,整个ScrollView将成为焦点,而不是任何内部容器。这也很有用,例如,当您在布局中有编辑文本并且您不希望它立即获得焦点并在进入屏幕时弹出键盘(这是相同的原则)。 / p>
因此,您布局顶部的ScrollView将如下所示:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollViewLuogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:background="#fff" >
答案 2 :(得分:5)
只需在父布局中添加这两行
即可android:focusable =“true” android:focusableInTouchMode =“true”
试试这个,希望它能为你效用
答案 3 :(得分:3)
如果您想以编程方式将其滚动到顶部/底部,则可以执行此操作(来自here):
焦点向下:
((ScrollView) findViewById(R.id.scrollView)).post(new Runnable() {
public void run() {
((ScrollView) findViewById(R.id.scrollView)).fullScroll(View.FOCUS_DOWN);
}
});
焦点到顶部
((ScrollView) findViewById(R.id.scrollView)).post(new Runnable() {
public void run() {
((ScrollView) findViewById(R.id.scrollView)).fullScroll(View.FOCUS_UP);
}
});
答案 4 :(得分:3)
ScrollView
android:fitsSystemWindows="false"
答案 5 :(得分:3)
只需在ScrollView的子代中添加这行代码
即可public class MyTestsuite extends TestSuite {
MyTestsuite() {
super(new Class[]{Test1.class, Test2.class});
}
public static Test suite() {
return new MyTestsuite();
}
}
答案 6 :(得分:2)
可悲的是,你所遵循的榜样非常糟糕。不应将ListViews和GridView放入ScrollViews。
ScrollView的目的是为其子视图提供无限高度。 List / GridView的目的是获取一个可能非常大的数据集,并且只生成足够的项目视图以填充一次可用的空间以提高效率。两者都能够在没有其他内容的情况下滚动内容。
在ScrollView中放置List / GridView就是说“不可阻挡的力量,遇见不可移动的对象”。要么你已经击败了List / GridView,要么通过组合它们来击败ScrollView。
在同一滚动区域中包含其他内容的更好方法包括使用带有ListView的页眉/页脚视图,或者将列表适配器的内容连接到一个适配器中。创建每行包含多个项目的ListView项目以形成适配器内容的一部分网格很简单。
答案 7 :(得分:0)
我找到了一种方法,可以将 GridView 固定大小放在ScrollView 中,然后启用滚动。这允许您在不必滚动GridView的所有元素的情况下查看整个ScrollView,使用 ExpandableHeightGridView 对我来说更有意义。
为此,您必须实现一个扩展GridView的新类,并覆盖 onTouchEvent()以调用 requestDisallowInterceptTouchEvent(true)。 因此,父视图将使网格拦截触摸事件。
GridViewScrollable.java:
package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;
public class GridViewScrollable extends GridView {
public GridViewAdjuntos(Context context) {
super(context);
}
public GridViewAdjuntos(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent ev){
// Called when a child does not want this parent and its ancestors to intercept touch events.
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
}
在ScrollView中添加您想要的特征和边距的布局:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="true" >
<com.example.GridViewScrollable
android:id="@+id/myGVS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth" />
</ScrollView>
在你的活动中得到它:
GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);
我希望它有帮助=)
答案 8 :(得分:0)
作为后续行动,我也会分享我的痛苦。在我的应用中,RecyclerView
内的NestedScrollView
内有一个CoordinatorLayout
:
<CoordinatorLayout>
<NestedScrollView id="@+id/content">
.......
<TextView android:id="@+id/header"/>
<RecyclerView android:id="@+id/recyclerView"/>
</NestedScrollView>
</CoordinatorLayout>
当然,在打开活动时,页面会滚动到中间包含recyclerView。上面的答案都没有奏效,所以我提出了以下解决方案:
@Override
protected void onCreate( Bundle savedInstanceState ) {
....
content.setOnScrollChangeListener( new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange( NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY ) {
Rect scrollBounds = new Rect();
v.getHitRect( scrollBounds );
if( header.getLocalVisibleRect( scrollBounds ) ){
if( View.VISIBLE != recyclerView.getVisibility() ){
recyclerView.setVisibility( View.VISIBLE );
fillRecyclerViewSomehow();
}
}
}
}
}
@Override
protected void onResume() {
...
recyclerView.setVisibility( View.GONE ); // this effectively suppresses the focusability
}
HTH
答案 9 :(得分:0)
实现此目的的简单方法是在XML中为ScrollView设置一个ID ...说
scrollView_main
在那之后,您只需要转到您的java文件并像在onCreate过程上方的普通变量一样声明它,就可以像这样是一个全局变量
ScrollView scrollView_main;
好,现在是时候进行onCreate过程并声明它了,以从XML文件获取与您的ID的连接
scrollView_main = (ScrollView)findViewById(R.id.scrollView_main);
最后是将ScrollView滚动到顶部的技巧,这就是您的答案
scrollView_main.smoothScrollTo(0,0); //set it on top
答案 10 :(得分:0)
如果没有任何效果,请将其作为scrollView的单个子元素的第一个元素:
<EditText
android:layout_width="0dp"
android:layout_height="0dp"/>
示例:
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="0dp"
android:layout_height="0dp"/>
<!-- your other views -->
</LinearLayout>
</ScrollView>
答案 11 :(得分:0)
我遇到了类似的问题,而有些完全不同的问题对我有用。我有以下几种视图层次结构-
<LinearLayout>
<ImageView />
<ScrollView>
<TextView android:id="header_tv"/>
<TabLayout />
<ViewPager2 />
</ScrollView>
</LinearLayout>
用于打开的视图已经滚动到视图寻呼机。我只是将 android:focusable =“ true” 添加到滚动视图的第一个元素中来解决此问题,如下所示-
<LinearLayout>
<ImageView />
<ScrollView>
<TextView
android:id="header_tv"
android:focusable="true" />
<TabLayout />
<ViewPager2 />
</ScrollView>
</LinearLayout>