web-dev-qa-db-ja.com

Android ScrollViewは先頭からではなく、GridViewの先頭から開始します

内部にパーソナライズされた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の上部から画面の上部までの高速アニメーションを作成し、私はそれが好きではありません。

なにか提案を??

52
user2328149

溶液:

返信が遅いのに申し訳ありませんが、同じ問題(私は代わりにListViewを使用していたということだけ)につまずいて、少し試行錯誤して解決策が見つかりましたこれに:

基本的に問題は、GridView/ListView子がExpandableHeightGridViewでコンテンツを「ハッキング」およびサイズ変更するときに、自動的に親フォーカス(ScrollView)を要求するという事実にあります。これはレイアウトがレンダリングされた後に発生するため、scrollTo()で上にスクロールしようとするとアニメーションが表示されます(AFTERレイアウトが作成され、AFTER gridViewがサイズ変更されるため、汎用コールバックはプログラムで処理できません)。

そのため、私が見つけた最も簡単な解決策は、ListView/GridViewのフォーカス可能なプロパティを次のように無効にすることです。

listView.setFocusable(false);

こうすることで、最初にアクティビティを入力したときに、フォーカスがデフォルトになり、Listview/GridViewに依存しなくなります。

そして、すべて正常に動作します=)

166

最も簡単な方法は、親の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" >
21
Disruption

この2行を親レイアウトに追加するだけです

Android:focusable = "true" Android:focusableInTouchMode = "true"

これを試して、それがあなたのために働くことを願っています

このコード行をScrollViewの子に追加するだけです

Android:focusableInTouchMode="true"
4
Bilal Ahmad

プログラムで上/下にスクロールしたい場合は、これを行うことができます( 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); 
    } 
});
3
Piasy

ScrollView

Android:fitsSystemWindows="false"
3
Matheus Marques

悲しいことに、あなたが従った例は非常に貧弱です。 ListViewsとGridViewsをScrollViewsに配置しないでください。

ScrollViewの目的は、その子ビューに無限の高さを与えることです。 List/GridViewの目的は、潜在的に非常に大きなデータセットを取得し、効率のために一度に利用可能なスペースを埋めるために十分なアイテムビューのみを生成することです。どちらも、他のコンテンツなしでコンテンツをスクロールできます。

ScrollViewにList/GridViewを置くことは、「止められない力、不動のオブジェクトに出会う」と言っています。 List/GridViewのポイントを無効にするか、ScrollViewのポイントをそれらを組み合わせて無効にします。

同じスクロール領域内に他のコンテンツを含めるより良い方法には、ListViewでヘッダー/フッタービューを使用する方法、またはリストアダプターのコンテンツを単一のアダプターに連結する方法があります。アダプターのコンテンツの一部のグリッドを形成するために、行ごとに複数のアイテムを含むListViewアイテムを作成するのは簡単です。

2
adamp

これを実現する簡単な方法は、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
1

フォローアップとして、痛みも共有します。私のアプリでは、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

0
injecteer

何も機能しない場合は、これを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>
0
Kishita

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);

私はそれが役立つことを願っています=)

0
Lionel T.