IT story

내 Android 활동이 항상 맨 아래로 스크롤되기 시작하는 이유는 무엇입니까?

hot-time 2020. 9. 12. 11:32
반응형

내 Android 활동이 항상 맨 아래로 스크롤되기 시작하는 이유는 무엇입니까?


이 활동을 시작할 때마다 항상 맨 아래로 시작하여 맨 아래로 스크롤됩니다. 나는 스크롤 위치를 변경할 것으로 예상되는 OnCreate 활동 (또는 그 문제에 대한 모든 곳)에서 이상한 일을하고 있지 않습니다. 포커스를 맨 위의 포커스 가능한 컨트롤과 scrollto 메서드로 설정하려고 시도했지만 둘 다 작동하지 않습니다. 게다가 내 다른 활동에는이 문제가 없습니다. 레이아웃은 다음과 같습니다.

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/edit_refresh_update_header"
            android:textSize="18sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Variable:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_variables_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Network:"
            android:textSize="18sp"/>

        <RadioGroup
            android:id="@+id/widget1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical">

            <RadioButton
                android:text="Web"
                android:id="@+id/edit_refresh_update_rb_web"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"
                android:checked="true"/>

            <RadioButton
                android:text="Socket Server"
                android:id="@+id/edit_refresh_update_rb_socket_server"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"/>
        </RadioGroup>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server request type:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_socket_server_req_types_spinner"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server body:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_ss_body"
            android:layout_height="wrap_content"
            android:enabled="false"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Url:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_url"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <Button
            android:text="Save refresh update"
            android:id="@+id/edit_refresh_save_btn"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginBottom="20dp"
            android:layout_alignParentBottom="true"
            android:onClick="SaveRefreshUpdate">
        </Button>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>
    </LinearLayout>
</ScrollView>

When Android starts an activity, some control needs to take focus. When there's no designated control to take focus, the system chooses the first eligible control that wants focus. If you set the following property in your LinearLayout - android:focusableInTouchMode="true" your LinearLayout will be focused on start and your activity won't scroll to EditText in the bottom.


Instead of polluting items in your layout, you can add this into your Activity/Class:

    ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
    scrollView.setFocusableInTouchMode(true); 
    scrollView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

This way it isn't an element within your scrollView getting focus, it's your scrollView as a container which get's the first focus, moving onto the child view's after this.


You can try this code:

scroller.post(new Runnable() { 
    public void run() { 
        scroller.fullScroll(ScrollView.FOCUS_DOWN); 
    } 
}); 

[N:B] [referance link]1


Along with what devmiles.com said.

If you set the following property in your LinearLayout - android:focusableInTouchMode="true" your LinearLayout will be focused on start and your activity won't scroll to EditText in the bottom.

If you call requestLayout() on a view at the bottom of your linear layout it might steal the focus from your top most view. So just call requestFocus() on the top most view in the linear layout after calling requestLayout() on a lower view.


Have you tried use fullScroll method ?http://developer.android.com/reference/android/widget/ScrollView.html#fullScroll(int)

yourScrollView.fullScroll(ScrollView.FOCUS_UP);

For Xamarin Android development, if you want to do @Graeme solution then:

// Set Focus to ScrollView
ScrollView scrollView = (ScrollView)FindViewById(Resource.Id.scrollView);
scrollView.FocusableInTouchMode = true;
scrollView.DescendantFocusability = Android.Views.DescendantFocusability.BeforeDescendants;

Just make it not focusable in onCreate()

editText.setFocusable(false);

and use

editText.setOnClickListener(new ....){
 ......
  editText.setFocusable(true);
  editText.setFocusableInTouchMode(true);
  editText.requestFocus();

  showSoftKeyboard(); //Use InputMethodManager to open soft Keyboard

 ......
 };

and it will not scroll down to Edittext next time, a fragment or activity is created.


I don't know why but you could experiment with

ScrollView sv = (ScrollView) findViewById(R.id.scroll);
sv.scrollTo(0,0);

in your onCreate to manually scroll it to where you like it to be.


scrollView.requestFocus(View.FOCUS_UP) solved my problem when I wanted the top view to be visible. Specifying direction parameter to the method requestFocus(int direction) is a good way to control the ScrollView position. More details here.


Add these two lines in your ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"

In my case I had a VideoView inside a ConstraintLayout inside a ScrollView. The VideoView was always stealing focus, and there are issues with it. Solution is to use a TextureView. Hopefully this helps someone, it cost me an hour at least :)

참고URL : https://stackoverflow.com/questions/9690246/why-does-my-android-activity-always-start-scrolled-to-the-bottom

반응형