Tại sao hoạt động Android của tôi luôn bắt đầu được cuộn xuống dưới cùng?


91

Bất cứ khi nào tôi bắt đầu hoạt động này, nó luôn bắt đầu từ dưới lên - được cuộn xuống dưới cùng. Tôi không làm bất cứ điều gì kỳ lạ trong hoạt động OnCreate (hoặc bất kỳ nơi nào cho vấn đề đó) mà tôi mong đợi để thay đổi vị trí cuộn. Tôi đã thử đặt tiêu điểm thành điều khiển có thể lấy tiêu điểm trên cùng và phương pháp cuộn, nhưng cả hai đều không hoạt động. Ngoài ra, không có hoạt động nào khác của tôi gặp sự cố này. Đây là bố cục:

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

Chính xác thì bạn đã cố gắng thay đổi tiêu điểm như thế nào?
devmiles.com

1
sử dụng phương thức fulscroll như được mô tả bên dưới và phương thức scrollto như được mô tả bên dưới. Tôi không nhất thiết phải sửa nó theo cách này, nhưng phải có lý do tại sao nó bắt đầu như vậy và tôi muốn sửa nó bằng cách sửa nó.
MrGibbage

Câu trả lời:


306

Khi Android bắt đầu một hoạt động, một số kiểm soát cần phải tập trung. Khi không có điều khiển được chỉ định nào để lấy tiêu điểm, hệ thống sẽ chọn điều khiển đủ điều kiện đầu tiên muốn lấy tiêu điểm. Nếu bạn đặt thuộc tính sau trong LinearLayout của mình - android:focusableInTouchMode="true"của bạn LinearLayoutsẽ được tập trung vào lúc bắt đầu và hoạt động của bạn sẽ không cuộn EditTextxuống dưới cùng.


Không hoạt động trong GridLayout của tôi. Tôi có GridView ở giữa bố cục và nó luôn lấy tiêu điểm.
Iqbal

2
Tôi vò đầu bứt tai suốt một ngày và không thể tìm ra lý do tại sao nó lại xảy ra chỉ trong một hoạt động cụ thể và tôi vẫn không hiểu vì tôi chưa bật tiêu điểm trên bất kỳ chế độ xem nào. Nhưng nhờ có bạn, tôi đã khắc phục được sự cố này. Sẽ thật tuyệt nếu ai đó có thể làm sáng tỏ điều gì có thể là lý do khả dĩ vì tôi không có gì mới trong hoạt động mới.
Shubhral

2
Một lưu ý quan trọng: cái này sẽ được thêm vào dưới dạng thuộc tính vào LinearLayoutbên trong ScrollViewchứ không phải vào chính chế độ xem cuộn.
Boris Strandjev

@BorisStrandjev lưu ý rất quan trọng. Nên được thêm vào câu trả lời. Nhân tiện, cảm ơn vì điều đó: P
Coreggon

Nó được đề cập theo nghĩa đen trong câu trả lời.
devmiles.com

35

Thay vì các mục gây ô nhiễm trong bố cục của bạn, bạn có thể thêm mục này vào Hoạt động / Lớp học của mình:

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

Bằng cách này, nó không phải là một phần tử bên trong scrollView của bạn đang nhận được tiêu điểm, mà đó là scrollView của bạn như một vùng chứa lấy tiêu điểm đầu tiên, chuyển sang chế độ xem con sau phần này.


Một phần làm việc cho tôi khi tôi cố gắng để chiều cao bộ ListView dựa trên trẻ em bên trong scrollview
Konstantin Konopko

Điều này đã giúp! (trong khi các thuộc tính như nhau trong xml đã không làm việc ..)
Matan Dahan

Hoạt động như một sự quyến rũ! Thx
Bogy

Nó đã hoạt động đối với tôi, nhưng tôi đã thêm dòng này: scrollView.fullScroll (ScrollView.FOCUS_UP) Cả hai riêng biệt đều không hoạt động.
Juan Giorello,

3

Bạn có thể thử mã này:

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

[N: B] [liên kết giới thiệu] 1


1
một lựa chọn tốt của nó nhưng nó mô phỏng một kẻ ngớ ngẩn sau khi mở nên không phải là một trải nghiệm người dùng tốt tôi nghĩ rằng
iBabur

2

Cùng với những gì devmiles.com đã nói.

Nếu bạn đặt thuộc tính sau trong LinearLayout - android: focusableInTouchMode = "true" thì LinearLayout của bạn sẽ được tập trung vào lúc bắt đầu và hoạt động của bạn sẽ không cuộn đến EditText ở dưới cùng.

Nếu bạn gọi requestLayout () trên một chế độ xem ở dưới cùng của bố cục tuyến tính, nó có thể đánh cắp tiêu điểm từ chế độ xem trên cùng của bạn. Vì vậy, chỉ cần gọi requestFocus () ở chế độ xem trên cùng trong bố cục tuyến tính sau khi gọi requestLayout () ở chế độ xem thấp hơn.


1

Bạn đã thử sử dụng phương thức fullScroll chưa? Http: //developer.android.com/reference/android/widget/ScrollView.html#fullScroll (int)

yourScrollView.fullScroll(ScrollView.FOCUS_UP);

1

Để phát triển Xamarin Android, nếu bạn muốn thực hiện giải pháp @Graeme thì:

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

1

Chỉ làm cho nó không thể tiêu điểm trong onCreate ()

editText.setFocusable(false);

Và sử dụng

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

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

 ......
 };

và nó sẽ không cuộn xuống Edittext vào lần sau, một phân đoạn hoặc hoạt động được tạo.


1

Thêm hai dòng này trong ScrollView

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

0

Tôi không biết tại sao nhưng bạn có thể thử nghiệm với

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

trong của bạn onCreateđể cuộn nó theo cách thủ công đến nơi bạn muốn.


0

scrollView.requestFocus(View.FOCUS_UP)đã giải quyết vấn đề của tôi khi tôi muốn hiển thị chế độ xem trên cùng. Chỉ định tham số hướng cho phương thức requestFocus(int direction)là một cách tốt để kiểm soát ScrollViewvị trí. Thêm chi tiết tại đây .


0

Trong trường hợp của tôi, tôi đã có một VideoViewbên trong một ConstraintLayoutbên trong a ScrollView. Nó VideoViewluôn ăn cắp tiêu điểm và có vấn đề với nó . Giải pháp là sử dụng a TextureView. Hy vọng rằng điều này sẽ giúp ai đó, tôi mất ít nhất một giờ :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.