こんばんは。
最近、「悪魔城ドラキュラx 血の輪廻」という横スクロールゲームをやったのですが、めちゃくちゃ難しかったです。
昔のゲームって鬼畜仕様多いですよね。
ってことでスクロールについての話題を。。
ScrollViewでスクロールが表示されているかを判定する方法
ScrollViewでスクロールが出ていた場合、メッセージ表示やレイアウト変更したいというケースが稀にあります。
例えば、下記のように文字追加を行いスクロールが出たら画面下部に「続きがあります」と表示したい場合など。。
方法としてはScrollViewとScrollViewの内側にいるLayoutViewの高さを比較し、LayoutViewの方が大きければスクロールが出ていると判断出来ます。
下の例だとscrollViewとscrollLayoutを比較。
具体的なソースはこちら
public class MainActivity extends AppCompatActivity { private TextView txtInfo; private ScrollView scrollView; private LinearLayout scrollLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button btnAdd = findViewById(R.id.btnAdd); final Button btnClear = findViewById(R.id.btnClear); final TextView textView = findViewById(R.id.textView1); txtInfo = findViewById(R.id.txtInfo); scrollView = findViewById(R.id.scrollView); scrollLayout = findViewById(R.id.scrollLayout); for (int i = 0; i < 10; i++) { textView.append("aaaaaa\n"); } // scrollLayoutがの可視状態が変わった場合または、変更があったい場合に動く scrollLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { setInfo(); // 初回描画時だけ判定したいのであれば、下記でイベントを削除する。 // scrollLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); btnAdd.setOnClickListener(v -> { textView.append("aaaaaa\n"); } ); btnClear.setOnClickListener(v -> { textView.setText(""); }); } private void setInfo() { // ScrollViewとScrollViewの内側にいるLayoutViewの高さを比較 if (scrollView.getHeight() <= scrollLayout.getHeight()) { txtInfo.setText("続きがあります。"); } else { txtInfo.setText(""); } } }
ポイントとしては「.getHeight()で高さをとっていますが描画後でないと正しい値が取れません。
onCreatenの中で「.getHeight()」で高さを取得してもScrollViewで描画が完了してない為、高さが0で返ってきてしまいます。
文字列追記後も描画反映まで少しラグがあるため、文字追加前の高さが取れます。
描画後に確実に判定するには、ViewTreeObserver.OnGlobalLayoutListenerで可視状態及び変更を監視し、LayoutViewの状態が変わったタイミングで判定する必要があります。