为什么我的机器人活动总是开始滚动到底部?

每当我开始这个活动,它总是开始触底-滚动所有的方式到底部。我没有在 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>
39705 次浏览

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.

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

yourScrollView.fullScroll(ScrollView.FOCUS_UP);

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.

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.

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.

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.

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

with Kotlin and ViewBinding u can add this in your fragment or activity :

binding.mainScroll.isFocusableInTouchMode = true
binding.mainScroll.descendantFocusability = ViewGroup.FOCUS_BEFORE_DESCENDANTS