内部にパーソナライズされたGridViewと他のビューのあるScrollViewに問題があります。アクティビティを初めて起動すると、ScrollViewはその上部から開始しますが、アクティビティにアクセスすると、ScrollViewが最初に開始しますGridView.Iの このリンク にあるExpandableHeightGridViewクラスをGridViewに使用しました。アクティビティレイアウトの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の上部から画面の上部までの高速アニメーションを作成し、私はそれが好きではありません。
なにか提案を??
溶液:
返信が遅いのに申し訳ありませんが、同じ問題(私は代わりにListViewを使用していたということだけ)につまずいて、少し試行錯誤して解決策が見つかりましたこれに:
基本的に問題は、GridView/ListView子がExpandableHeightGridViewでコンテンツを「ハッキング」およびサイズ変更するときに、自動的に親フォーカス(ScrollView)を要求するという事実にあります。これはレイアウトがレンダリングされた後に発生するため、scrollTo()で上にスクロールしようとするとアニメーションが表示されます(AFTERレイアウトが作成され、AFTER gridViewがサイズ変更されるため、汎用コールバックはプログラムで処理できません)。
そのため、私が見つけた最も簡単な解決策は、ListView/GridViewのフォーカス可能なプロパティを次のように無効にすることです。
listView.setFocusable(false);
こうすることで、最初にアクティビティを入力したときに、フォーカスがデフォルトになり、Listview/GridViewに依存しなくなります。
そして、すべて正常に動作します=)
最も簡単な方法は、親のScrollViewに次のxml属性を追加することです。
Android:descendantFocusability="beforeDescendants"
Android:focusableInTouchMode="true"
つまり、アクティビティを起動すると、ScrollView全体が内部コンテナではなくフォーカスを取得するものになります。これは、たとえば、レイアウト内に編集テキストがあり、画面に入るときにすぐにフォーカスを取得してキーボードをポップアップしたくない場合にも便利です(同じ原理です)。
したがって、レイアウトの上にある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行を親レイアウトに追加するだけです
Android:focusable = "true" Android:focusableInTouchMode = "true"
これを試して、それがあなたのために働くことを願っています
このコード行をScrollViewの子に追加するだけです
Android:focusableInTouchMode="true"
プログラムで上/下にスクロールしたい場合は、これを行うことができます( 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);
}
});
ScrollView
Android:fitsSystemWindows="false"
悲しいことに、あなたが従った例は非常に貧弱です。 ListViewsとGridViewsをScrollViewsに配置しないでください。
ScrollViewの目的は、その子ビューに無限の高さを与えることです。 List/GridViewの目的は、潜在的に非常に大きなデータセットを取得し、効率のために一度に利用可能なスペースを埋めるために十分なアイテムビューのみを生成することです。どちらも、他のコンテンツなしでコンテンツをスクロールできます。
ScrollViewにList/GridViewを置くことは、「止められない力、不動のオブジェクトに出会う」と言っています。 List/GridViewのポイントを無効にするか、ScrollViewのポイントをそれらを組み合わせて無効にします。
同じスクロール領域内に他のコンテンツを含めるより良い方法には、ListViewでヘッダー/フッタービューを使用する方法、またはリストアダプターのコンテンツを単一のアダプターに連結する方法があります。アダプターのコンテンツの一部のグリッドを形成するために、行ごとに複数のアイテムを含むListViewアイテムを作成するのは簡単です。
これを実現する簡単な方法は、ScrollViewにXMLでIDを設定することです...
scrollView_main
その後、Javaファイルに移動し、onCreateプロシージャの上の通常の変数のように宣言して、このようなグローバル変数にする必要があります。
ScrollView scrollView_main;
oK、onCreateプロシージャに進み、これを宣言して、XMLファイルからIDとの接続を取得します
scrollView_main = (ScrollView)findViewById(R.id.scrollView_main);
そして最後に、ScrollViewを上にスクロールするためのトリックを行うコード、これがあなたの答えです
scrollView_main.smoothScrollTo(0,0); //set it on top
フォローアップとして、痛みも共有します。私のアプリでは、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
何も機能しない場合は、これを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>
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);
私はそれが役立つことを願っています=)