【教えてください】ScrollViewでの子Viewへの自動スクロールについて

9,810 views
Skip to first unread message

micco

unread,
Feb 25, 2011, 11:36:59 PM2/25/11
to 日本Androidの会
こんにちは。
miccoです。

ScrollViewを使って縦長カレンダーを表示するアプリを作っていますが、
特定の子View(特定日の情報を表示するためのLinearLayout)まで自
動スクロールさせる方法がありましたら、ご教授頂ければ幸いです。

宜しくお願いいたします。

Kd

unread,
Feb 27, 2011, 9:48:28 PM2/27/11
to android-g...@googlegroups.com, micco
Rと申します。

View v = 特定のビュー(LinearLayout)
int y = v.getTop();

                ScrollView sv = (ScrollView)this.findViewById(R.id.scrollView1);
sv.smoothScrollTo(0, y);

                これをするとその特定のビューがScrollViewの一番上にきます。
                
                正しい方法かわかりませんがお試しください。

micco

unread,
Feb 28, 2011, 6:48:28 AM2/28/11
to 日本Androidの会
Rさん

こんばんは。
miccoです。

ご教授ありがとうございます。
さっそく試してみます。

micco

unread,
Feb 28, 2011, 7:31:53 AM2/28/11
to 日本Androidの会
こんばんは。
miccoです。

以下のように、ScrollView配下のButtonであるDay[target]の座標を取ってスクロール
させてみましたが、ダメでした。

int y = Day[target].getTop();
sv.smoothScrollTo(0,y);

getTop()がうまく機能していないのか、yには0が代入されていました。
yの部分に適当な座標数値を入れてみると、その座標から表示されることが確認できました。

お気づきの点がありましたら、何でも結構ですので、ご意見ください。
よろしくお願いいたします。
> > 正しい方法かわかりませんがお試しください。- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

Kd

unread,
Feb 28, 2011, 7:48:40 AM2/28/11
to android-g...@googlegroups.com

こんぼんわRです。

ふと思ったのですが、
最上位のview でgettop()
していますか?
もう一つ上位にview がないでしょうか?

2011/02/28 21:32 "micco" <gou...@gmail.com>:



こんばんは。
miccoです。

以下のように、ScrollView配下のButtonであるDay[target]の座標を取ってスクロール
させてみましたが、ダメでした。

int y = Day[target].getTop();
sv.smoothScrollTo(0,y);

getTop()がうまく機能していないのか、yには0が代入されていました。
yの部分に適当な座標数値を入れてみると、その座標から表示されることが確認できました。

お気づきの点がありましたら、何でも結構ですので、ご意見ください。
よろしくお願いいたします。


On 2月28日, 午後8:48, micco <gou...@gmail.com> wrote:
> Rさん
>
> こんばんは。
> miccoです。
>
> ご教授ありがとうございます。

> ...

> >                 正しい方法かわかりませんがお試しください。- 引用テキストを表示しない -
>
> - 引用テキストを表示 -


--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-group-japan@googlegroup...

micco

unread,
Feb 28, 2011, 8:14:25 AM2/28/11
to 日本Androidの会
Rさん

以下のような階層です。
ScrollView
LinearLayout1
LinearLayout2
Button ←これがtargetです

ScrollViewは1つしか子を持てないという制約から考えると、
最上位とおっしゃっているのは、LinearLayout2と同じ階層、
つまりLinearLayout1直下の子Viewということでしょうか?

この構造でgetTop()してもダメってことでしょうか?
お手数ですが、ご教授頂けたら幸いです。

micco

unread,
Feb 28, 2011, 8:28:35 AM2/28/11
to 日本Androidの会
お世話になります。
miccoです。

開発者ドキュメントを読むと、親Viewに対する位置を取得するメソッドのようです。
そうなると、レイアウトの構造を変えないといけないですね。
他に手立てがあればご教授頂ければ幸いです。。。
> > このグループに投稿するには、android-group-japan@googlegroup...- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

micco

unread,
Feb 28, 2011, 8:54:26 AM2/28/11
to 日本Androidの会
度々すみません。
miccoです。

構造を変えてみましたが、どうもうまくいきません。。。
レイアウトxmlでは、以下のように記述しています。
<ScrollView
android:id="@+id/sv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="none"
android:fadingEdgeLength="50dp"
>
<LinearLayout
android:id="@+id/main_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
</ScrollView>

そして、この「main_layout」なるLinearLayoutをコード側で取得して、このLinearLayoutに
LinearLayout(ButtonやTextViewを水平方向に配置)を日数分だけaddViewしています。
addViewした各LinearLayoutは、innerLayout[]という配列で保持し、以下のような形で座
標を取得しています。

int y = innerLayout[10].getTop();
Sv.smoothScrollTo(0,y);

結果は変わらずy=0でした。
おかしな点がありましたら、ご指摘ください。
よろしくお願いいたします。
> > - 引用テキストを表示 -- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

micco

unread,
Feb 28, 2011, 10:19:31 AM2/28/11
to 日本Androidの会
miccoです。
自己レスばかりでスミマセン。

色々試していますが、どうやらタイミングの問題のようです。
onCreateで高さや幅を取得しても0しか返ってこなかったため、onWindowFocusChangedをオーバーライドし、その中で自動スク
ロールを記述してみました。

public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
today_y = innerLayout[target].getTop();
Sv.smoothScrollTo(0,today_y);
}

すると、うまく動きましたが、他Activityへの遷移のたびに自動スクロールが呼び出されてしまいます。
このActivityに戻った際には、他Activityに遷移する直前の画面(スクロール位置)をキープしたいのですが、うまい方法はありますでしょ
うか?
または、onWindowFocusChanged以外で、初期描画時に1回だけ呼ばれるような適当なコールバックがあればご教授ください。

よろしくお願いいたします。

Kd

unread,
Feb 28, 2011, 7:02:20 PM2/28/11
to android-g...@googlegroups.com
おはようございます。Rです。
返事できなくてすいません。

僕はonClickListenerのときに、スクロールすることしか想定していなくて、このような問題があるとは思いませんでした(汗

onCreateでsv.smoothScrollTo(0, 500);
とかにすると動くことは動きますね。

しかし、スクロールしたい子ビューのY座標が取得できませんね・・・
onCreate,onStart,OnResumeでgetTop()を呼んでも戻り値は0ですね。
getHeight()も0です。

いろいろ考えれることはすべてやりましたが、onWindowFocusChangedしか僕も思いつきません

boolean isScrolled = false;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if ( ! isScrolled )
{
scroll(); //スクロールさせる
isScrolled = true;
}
}

これをすれば一応Activity遷移して戻っても大丈夫だと思います。(こんなんでいいのかな・・・)



他Activityに遷移する直前の画面(スクロール位置)をキープすることはできます。
sv.getScrollY()でいまのスクロールしているYは取れます。

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

ScrollView sv = (ScrollView)this.findViewById(R.id.ScrollView01);
outState.putInt("getScrollY()" , sv.getScrollY());
       }

画面縦横切り替え時は僕はこうやって今のYを保存して
onRestoreInstanceStateでsv.smoothScrollTo( 0, outState.getInt("getScrollY()"));で再設定しています。

こんなんでごめんなさい。
なにかいい方法があれば僕も知りたいです。

micco

unread,
Feb 28, 2011, 11:00:13 PM2/28/11
to 日本Androidの会
Rさん

こんにちは。
miccoです。

ご丁寧にコメント返して頂きまして、ありがとうございます!
前回の投稿後、私もフラグを立てて最初の1回だけスクロールするよう実装しました。
確かにご提案のように値を保持して再設定する方法もありますね。
ここは原始的にやるしかなさそうです。

実は、少しつまずいています。
最下部のViewのY座標を取ってスクロールさせたときに例外発生で落ちました。
手動でスクロールさせると、最下部のViewがScrollViewの一番下に来た時点で止まり
ますので、それよりも上にスクロールさせるよう指定していることが原因だと思います。
これは何らか計算してスクロール座標を調整する必要がありそうですね。。。
ちょっと悩んでみます。

Kd

unread,
Mar 1, 2011, 6:17:48 AM3/1/11
to android-g...@googlegroups.com
こんばんわRです。

こちらでは、スクロール量を10000とか-10000とかにしても例外は発生しないようです。

View v = this.findViewById(id);
int y = v.getTop();

int center = sv.getBottom()-sv.getTop();
center = center / 2;
center = center - (v.getHeight()/2);
y = y - center;
sv.smoothScrollTo(0, y);

僕はこんな感じで真ん中にくるようにしてます。

なんの例外なんでしょうか?

micco

unread,
Mar 1, 2011, 8:29:18 AM3/1/11
to 日本Androidの会
Rさん

こんばんは。
miccoです。

ごめんなさい、例外発生は別の問題でした・・・。
色々とありがとうございました!
助かりました。

kazutaka kamiya

unread,
Mar 31, 2012, 11:07:38 PM3/31/12
to android-g...@googlegroups.com


2011年3月1日13:00 micco <gou...@gmail.com>:
--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。




--
神谷です、お疲れ様です。
Reply all
Reply to author
Forward
0 new messages