搜尋

首頁  >  問答  >  主體

java - Fragment中的上下滑動事件會被上一個Fragment回應而不是目前的

我目前開發一個安卓app,只有一個activity,佈局檔案是中有一個ViewPager,其適配器綁了三個Fragment。前兩個Fragment的佈局檔案都是最外層SwipeRefreshLayout用於下拉刷新,然後嵌套一個ScrollView,第三個也準備這麼弄但是發現問題。

當我進入app預設顯示第一個Fragment時,上下滑動螢幕是有滑動效果的,然而切換到第二個Fragment滑動就沒效果。接著我發現,當我在第二個Fragment中滑動後,再切換回第一個Fragment,發現反而是第一個Fragment介面回應了我的滑動操作。於是我嘗試切換到第三個Fragment,滑動後迅速切換到第二個Fragment,果然其介面正在滑動。

我並不知道這個原因到底是什麼,但我試了一個辦法:透過重載setUserVisibleHint(),一旦離開一個Fragment,直接把整個Fragment設為Invisible,以這種方式,的確實現了滑動操作被目前Fragment回應。 但我還是弄不懂之前為什麼會有那樣的情況——在第一個和第二個Fragment中滑動屏幕,都是第一個Fragment響應,在第三個Fragment中滑動屏幕,則是第二個Fragment回應滑動操作。

我想知道,究竟出了什麼問題,是什麼原因導致的,我怎麼能解決(不透過設定Visibility的方法強行實現)?

Fragment佈局檔案程式碼(只給一個,另一個類似):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<code><?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:id="@+id/swipe_article_container"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <ScrollView

        android:id="@+id/scroll_article_container"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:descendantFocusability="blocksDescendants">

    <FrameLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent">

        <WebView

        android:id="@+id/articleWebView"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:alpha="0"/>

        <ProgressBar

            android:id="@+id/webViewLoading"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="center"

            style="@style/MyProgressBar"

            android:visibility="gone"/>

    </FrameLayout>

    </ScrollView>

</android.support.v4.widget.SwipeRefreshLayout></code>

某草草某草草2762 天前980

全部回覆(1)我來回復

  • 怪我咯

    怪我咯2017-05-31 10:39:03

    問題解決了。 。
    有一個資訊在問題中沒有描述。那就是,我為了讓ViewPager切換page時動畫為淡入淡出而不是預設的滑動,實作了ViewPager類別的一個介面ViewPager.PageTransformer。然後,我在Activity中實例化這個類,並執行mViewPager.setPageTransformer(true, pageTransformer);就可以將切換動畫設定成我自己寫的動畫。問題就出在這個動畫上,一開始這個介面我是這麼實現的:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    <code>import android.support.v4.view.ViewPager;

    import android.view.View;

     

    /*

    *设置Fragment切换时的动画为淡入淡出

    */

     

    public class NoSlidingPageTransformer implements ViewPager.PageTransformer {

        private static final float MIN_ALPHA = 0.0f;    //最小透明度

     

        public void transformPage(View view, float position) {

            int pageWidth = view.getWidth();    //得到view宽

     

            if (position < -1) { // [-Infinity,-1)

                // This page is way off-screen to the left. 出了左边屏幕

                view.setAlpha(0);

     

            } else if (position <= 1) { // [-1,1]

                view.setTranslationX(-pageWidth * position);  //阻止页面的滑动

                float alphaFactor = Math.max(MIN_ALPHA, 1 - Math.abs(position));

                //透明度改变

                view.setAlpha(alphaFactor);

                if (alphaFactor == 0)

                    view.setVisibility(View.INVISIBLE);     //页面不在当前界面显示,则使其Invisible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因

                else if (view.getVisibility() == View.INVISIBLE)

                    view.setVisibility(View.VISIBLE);       //页面在当前界面显示,则使其Visible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因

            } else { // (1,+Infinity]

                // This page is way off-screen to the right.    出了右边屏幕

                view.setAlpha(0);

            }

        }

     

    }</code>

    其中這段程式碼是我臨時用來解決問題中所描述的「靈異」現象的:

    1

    2

    3

    4

    <code>if (alphaFactor == 0)

        view.setVisibility(View.INVISIBLE);     //页面不在当前界面显示,则使其Invisible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因

        else if (view.getVisibility() == View.INVISIBLE)

            view.setVisibility(View.VISIBLE);       //页面在当前界面显示,则使其Visible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因</code>

    問題在哪裡呢?問題就在view.setTranslationX()這個函數上,這個函數所設定的view的位置,不只是視覺上的,也是實際的位置,那麼看我實現的這段程式碼,在view離開目前介面的時候, position的值處於[-Infinity,-1]和[1,+Infinity]的時候,我並沒有用setTranslationX()將其位置設置到當前界面之外,而是還是與新出現的view在同一位置,只不過因為用setAlpha()設定了透明度才看不見的。
    我是怎麼發現這個問題的呢?就是把這個類別中的呼叫selAlpha()的程式碼全註解掉,再次運行,終於發現,當我切換Fragment的時候,會出現兩個Fragment重疊顯示的現象。現在我將這個類別修改如下,問題解決(臨時程式碼註解掉了):

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    <code>import android.support.v4.view.ViewPager;

    import android.view.View;

     

    /*

    *设置Fragment切换时的动画为淡入淡出

    */

     

    public class NoSlidingPageTransformer implements ViewPager.PageTransformer {

     

        public void transformPage(View view, float position) {

            int pageWidth = view.getWidth();    //得到view宽

     

            if (position <= -1) { // [-Infinity,-1]

                // This page is way off-screen to the left. 出了左边屏幕

                view.setTranslationX(0);

     

            } else if (position < 1) { // (-1,1)

                view.setTranslationX(-pageWidth * position);  //阻止页面的滑动,位置在左则设向右偏移位置,在右则设向左偏移位置

                float alphaFactor = 1 - Math.abs(position);

                //透明度改变

                view.setAlpha(alphaFactor);

                /*

                if (alphaFactor == 0)

                    view.setVisibility(View.INVISIBLE);     //页面不在当前界面显示,则使其Invisible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因

                else if (view.getVisibility() == View.INVISIBLE)

                    view.setVisibility(View.VISIBLE);       //页面在当前界面显示,则使其Visible,这句是为了解决Fragment对上下滑动事件监听的错乱,暂不知原因

                    */

            } else { // [1,+Infinity]

                // This page is way off-screen to the right.    出了右边屏幕

                view.setTranslationX(0);

            }

        }

     

    }</code>

    回覆
    0
  • 取消回覆