Android:完美解決ScrollView與嵌套EditText的滑動衝突

背景

一個 ScrollView 裏嵌着一個 EditText(設置可滑動)。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <EditText
                android:id="@+id/mEditText"
                android:layout_width="300dp"
                android:layout_height="300dp"
                android:maxLines="8"
                android:scrollbars="vertical"
                android:textAppearance="?android:attr/textAppearanceLarge" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:text="Android"
                android:textAppearance="?android:attr/textAppearanceLarge" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    ScrollView mScrollView;
    EditText mEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScrollView = findViewById(R.id.scrollView);
        mEditText = findViewById(R.id.mEditText);
}

問題

mScrollView 可滑動,但裏面設置的 mEditText 不可滑動。


原因分析

mScrollView把事件消費掉了,沒有傳遞到EditText,從而導致沒法使得 EditText 響應事件


解決思路

  • 當觸摸的是EditText & 當前EditText可滾動時,則將事件交給EditText處理,即進行滾動
  • 否則將事件交由其父類處理,即交給ScrollView進行滾動

具體實現方案

複寫EditTextonTouch()並 採用 requestDisallowInterceptTouchEvent(true)進行觸碰事件攔截

關於爲什麼可以攔截事件,可以看看我寫的事件分發機制:Android事件分發機制 詳解攻略,您值得擁有

public class MainActivity extends AppCompatActivity {

    ScrollView mScrollView;
    EditText mEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScrollView = findViewById(R.id.scrollView);
        mEditText = findViewById(R.id.mEditText);

        // 複寫EditText的onTouch方法
        mEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 當觸摸的是EditText & 當前EditText可滾動時,則將事件交給EditText處理;
                if ((v.getId() == R.id.mEditText && canVerticalScroll(mEditText))) {
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    // 否則將事件交由其父類處理
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        v.getParent().requestDisallowInterceptTouchEvent(false);
                    }
                }
                return false;
            }
        });
    }

    // 判斷當前EditText是否可滾動
    private boolean canVerticalScroll(EditText editText) {

        if (editText.getLineCount() > editText.getMaxLines()) {
            return true;
        }
        return false;
    }
}
  • 這樣,就能很好地解決ScrollView與嵌套的EditText滑動衝突問題哦。

  • 接下來我將繼續介紹 Android開發中的相關知識,感興趣的同學可以繼續關注本人博客Carson_Ho的開發筆記

請幫頂 / 點贊!因爲你的鼓勵是我寫作的最大動力!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章