CollapsingToolbarLayout ไม่รู้จักการเลื่อนแบบเลื่อน


94

ฉันได้สร้างCollapsingToolbarLayoutแบบง่ายๆแล้วและมันก็ใช้งานได้อย่างมีเสน่ห์ ปัญหาของฉันคือถ้าฉันพยายามใช้การเลื่อนแบบพลิกบนมุมมองที่ซ้อนกันมันจะหยุดเมื่อฉันปล่อยนิ้ว การเลื่อนปกติจะใช้งานได้ตามที่ควร

รหัสกิจกรรมของฉันไม่เปลี่ยนแปลง =>สร้างกิจกรรมว่างโดยอัตโนมัติ (ฉันเพิ่งคลิกสร้างกิจกรรมว่างใหม่ใน android studio และแก้ไข XML แล้ว)

ผมอ่านที่นี่ที่ท่าทางเลื่อนบน IMAGE ดูตัวเองมีรถ แต่ไม่ว่าการเลื่อนตัวเองเป็นรถ: ดูที่นี่

ฉันพยายามเปิดใช้งาน"การเลื่อนอย่างราบรื่น"ผ่านรหัสจาวา ดูเหมือนว่าถ้าฉันเลื่อนไปไกลพอที่จะมองไม่เห็นมุมมองภาพอีกต่อไปท่าทางการเหวี่ยงจะถูกจดจำ

TLDR:เหตุใดท่าทางการเหวี่ยงจึงไม่ทำงานตราบเท่าที่มองเห็นภาพได้ รหัส XML ของฉันมีลักษณะดังนี้:

    <android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/profile_app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/profile_collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp"
            android:fitsSystemWindows="true">

            <ImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="420dp"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                android:src="@drawable/headerbg"
                android:maxHeight="192dp"

                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        app:layout_anchor="@id/profile_app_bar_layout"
        app:layout_anchorGravity="bottom|right|end"
        android:layout_height="@dimen/fab_size_normal"
        android:layout_width="@dimen/fab_size_normal"
        app:elevation="2dp"
        app:pressedTranslationZ="12dp"
        android:layout_marginRight="8dp"
        android:layout_marginEnd="8dp"/>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/profile_content_scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_gravity="fill_vertical"
        android:minHeight="192dp"
        android:overScrollMode="ifContentScrolls"
        >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/LoremIpsum"/>

        </RelativeLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

น่าสนใจฉันบันทึกเหตุการณ์การสัมผัสในมุมมองการเลื่อนที่ซ้อนกันระหว่างการพุ่งที่ได้รับผลกระทบ ACTION_DOWN y=98 -> ACTION_MOVE y=-40 -> ACTION_MOVE y=-33 -> ACTION_UP y=97จะได้รับ ดูเหมือนว่าเหตุการณ์สัมผัสสุดท้ายจะรายงานตัวเองผิดว่าอยู่ถัดจากเหตุการณ์แรก
เสี่ยว

คุณกำลังใช้ไลบรารีสนับสนุนการออกแบบเวอร์ชันใด
Radu Topor

คุณกำลังเอาชนะเหตุการณ์การสัมผัสหรือไม่? ลองตั้งค่าnestedScrollView.getParent().requestDisallowInterceptTouchEvent(true);เป็นมุมมองแบบเลื่อนซ้อนของคุณ
Bhargav

คำตอบ:


20

ฉันได้ว่าปัญหาเดียวกันกับCollapsingToolbarLayoutกับImageViewภายในและNestedScrollView การเลื่อนจะหยุดเมื่อปล่อยนิ้ว

อย่างไรก็ตามฉันสังเกตเห็นบางอย่างแปลก ๆ หากคุณเริ่มเลื่อนโดยใช้นิ้วของคุณจากมุมมองด้วย OnClickListener (เช่นปุ่ม) การเลื่อนแบบเหวี่ยงจะทำงานได้อย่างสมบูรณ์

ดังนั้นฉันจึงแก้ไขด้วยวิธีแก้ปัญหาแปลก ๆ ชุด OnClickListener (ที่ไม่ทำอะไรเลย) ในเด็กโดยตรงของNestedScrollView แล้วมันก็ทำงานได้อย่างสมบูรณ์แบบ!

<android.support.v4.widget.NestedScrollView 
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

  <LinearLayout
      android:id="@+id/content_container"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">

    <!-- Page Content -->

  </LinearLayout>

</android.support.v4.widget.NestedScrollView>

ให้ id ลูกโดยตรง (LinearLayout) และตั้งค่า OnClickListener ในกิจกรรม

ViewGroup mContentContainer = (ViewGroup) findViewById(R.id.content_container);    
mContentContainer.setOnClickListener(this);

@Override
public void onClick(View view) {
    int viewId = view.getId();
}

หมายเหตุ:

ทดสอบโดยใช้ Support Design Library 25.0.1

CollapsingToolbarLayout ด้วย scrollFlags = "scroll | enterAlwaysCollapsed"


AOSP ควรได้รับการแก้ไขด้วยโซลูชันที่ยอดเยี่ยมนี้: D
deviant

ควรได้รับการโหวตมากกว่านี้ฮ่า ๆ Btw สิ่งนี้ทำให้ CollapsingToolbarLayout ไวต่อการเลื่อนมาก แต่ดีกว่าพฤติกรรมที่เสียในปัจจุบัน
Ahmad Fadli

1
มันดีเกินไปที่จะเป็นจริงดังนั้นฉันจึงลองและมันไม่ได้ผลสำหรับฉัน
Gilbert Mendoza

นี่เป็นวิธีแก้ปัญหาที่บ้าคลั่งที่สุดที่ฉันได้ลองใช้ใน SO
Techfist

: D ข้อสังเกตดีๆ @jinang !!
ศรีชาคราธา

10

ฉันรู้ว่ามีการถามคำถามนี้เมื่อปีที่แล้ว แต่ดูเหมือนว่าปัญหานี้จะยังไม่ได้รับการแก้ไขในไลบรารีการสนับสนุน / การออกแบบ คุณสามารถติดดาวปัญหานี้เพื่อให้อยู่ในลำดับความสำคัญมากขึ้น

ที่กล่าวว่าฉันลองใช้วิธีแก้ปัญหาที่โพสต์ส่วนใหญ่สำหรับสิ่งนี้รวมถึงแพทริค-iv ที่ไม่ประสบความสำเร็จ วิธีเดียวที่ฉันสามารถทำงานได้คือเลียนแบบการพุ่งและเรียกมันโดยทางโปรแกรมหากตรวจพบชุดเงื่อนไขบางอย่างในonPreNestedScroll(). ในไม่กี่ชั่วโมงของการดีบักฉันสังเกตเห็นว่าonNestedFling()ไม่เคยถูกเรียกให้พุ่งขึ้น (เลื่อนลง) และดูเหมือนว่าจะหมดก่อนเวลาอันควร ฉันไม่สามารถพูดได้ด้วยความมั่นใจ 100% สิ่งนี้จะใช้ได้กับการใช้งาน 100% แต่มันก็ใช้ได้ดีพอสำหรับการใช้งานของฉันดังนั้นฉันจึงตกลงกับสิ่งนี้แม้ว่ามันจะค่อนข้างแฮ็คและไม่ใช่สิ่งที่ฉันอยากทำ

public class NestedScrollViewBehavior extends AppBarLayout.Behavior {

    // Lower value means fling action is more easily triggered
    static final int MIN_DY_DELTA = 4;
    // Lower values mean less velocity, higher means higher velocity
    static final int FLING_FACTOR = 20;

    int mTotalDy;
    int mPreviousDy;
    WeakReference<AppBarLayout> mPreScrollChildRef;

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
                                  View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        // Reset the total fling delta distance if the user starts scrolling back up
        if(dy < 0) {
            mTotalDy = 0;
        }
        // Only track move distance if the movement is positive (since the bug is only present
        // in upward flings), equal to the consumed value and the move distance is greater
        // than the minimum difference value
        if(dy > 0 && consumed[1] == dy && MIN_DY_DELTA < Math.abs(mPreviousDy - dy)) {
            mPreScrollChildRef = new WeakReference<>(child);
            mTotalDy += dy * FLING_FACTOR;
        }
        mPreviousDy = dy;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child,
                                       View directTargetChild, View target, int nestedScrollAxes) {
        // Stop any previous fling animations that may be running
        onNestedFling(parent, child, target, 0, 0, false);
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout parent, AppBarLayout abl, View target) {
        if(mTotalDy > 0 && mPreScrollChildRef != null && mPreScrollChildRef.get() != null) {
            // Programmatically trigger fling if all conditions are met
            onNestedFling(parent, mPreScrollChildRef.get(), target, 0, mTotalDy, false);
            mTotalDy = 0;
            mPreviousDy = 0;
            mPreScrollChildRef = null;
        }
        super.onStopNestedScroll(parent, abl, target);
    }
}

และนำไปใช้กับ AppBar

AppBarLayout scrollView = (AppBarLayout)findViewById(R.id.appbar);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)scrollView.getLayoutParams();
params.setBehavior(new NestedScrollViewBehavior());

การสาธิต CheeseSquare: Before After


มันดีกว่าไม่มีอะไรเลย แต่ไม่ใช่สิ่งที่ผู้ใช้ Android ที่มีประสบการณ์จะคาดหวัง ขอบคุณสำหรับการเชื่อมโยงปัญหาฉันได้ติดดาวแล้ว
Raphael Royer-Rivard

ต้องลบenterAlwayslayout_ScrollFlag เพื่อให้ใช้งานได้ แต่ตอนนี้ทำงานได้ดี
Alexandre G

3

ฉันลองใช้วิธีแก้ปัญหาของ Floofer แล้ว แต่ก็ยังไม่ดีพอสำหรับฉัน ดังนั้นฉันจึงคิดพฤติกรรมของเขาในเวอร์ชันที่ดีขึ้น ตอนนี้ AppBarLayout ขยายและยุบได้อย่างราบรื่นเมื่อเหวี่ยง

หมายเหตุ:ฉันใช้การสะท้อนเพื่อแฮ็ควิธีนี้ดังนั้นมันอาจไม่ทำงานอย่างสมบูรณ์แบบกับไลบรารี Android Design เวอร์ชันที่แตกต่างจาก 25.0.0

public class SmoothScrollBehavior extends AppBarLayout.Behavior {
    private static final String TAG = "SmoothScrollBehavior";
    //The higher this value is, the faster the user must scroll for the AppBarLayout to collapse by itself
    private static final int SCROLL_SENSIBILITY = 5;
    //The real fling velocity calculation seems complex, in this case it is simplified with a multiplier
    private static final int FLING_VELOCITY_MULTIPLIER = 60;

    private boolean alreadyFlung = false;
    private boolean request = false;
    private boolean expand = false;
    private int velocity = 0;
    private int nestedScrollViewId;

    public SmoothScrollBehavior(int nestedScrollViewId) {
        this.nestedScrollViewId = nestedScrollViewId;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
                                  View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        if(Math.abs(dy) >= SCROLL_SENSIBILITY) {
            request = true;
            expand = dy < 0;
            velocity = dy * FLING_VELOCITY_MULTIPLIER;
        } else {
            request = false;
        }
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child,
                                       View directTargetChild, View target, int nestedScrollAxes) {
        request = false;
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout appBarLayout, View target) {
        if(request) {
            NestedScrollView nestedScrollView = (NestedScrollView) coordinatorLayout.findViewById(nestedScrollViewId);
            if (expand) {
                //No need to force expand if it is already ready expanding
                if (nestedScrollView.getScrollY() > 0) {
                    int finalY = getPredictedScrollY(nestedScrollView);
                    if (finalY <= 0) {
                        //since onNestedFling does not work to expand the AppBarLayout, we need to manually expand it
                        expandAppBarLayoutWithVelocity(coordinatorLayout, appBarLayout, velocity);
                    }
                }
            } else {
                //onNestedFling will collapse the AppBarLayout with an animation time relative to the velocity
                onNestedFling(coordinatorLayout, appBarLayout, target, 0, velocity, true);

                if(!alreadyFlung) {
                    //TODO wait for AppBarLayout to be collapsed before scrolling for even smoother visual
                    nestedScrollView.fling(velocity);
                }
            }
        }
        alreadyFlung = false;
        super.onStopNestedScroll(coordinatorLayout, appBarLayout, target);
    }

    private int getPredictedScrollY(NestedScrollView nestedScrollView) {
        int finalY = 0;
        try {
            //With reflection, we can get the ScrollerCompat from the NestedScrollView to predict where the scroll will end
            Field scrollerField = nestedScrollView.getClass().getDeclaredField("mScroller");
            scrollerField.setAccessible(true);
            Object object = scrollerField.get(nestedScrollView);
            ScrollerCompat scrollerCompat = (ScrollerCompat) object;
            finalY = scrollerCompat.getFinalY();
        } catch (Exception e ) {
            e.printStackTrace();
            //If the reflection fails, it will return 0, which means the scroll has reached top
            Log.e(TAG, "Failed to get mScroller field from NestedScrollView through reflection. Will assume that the scroll reached the top.");
        }
        return finalY;
    }

    private void expandAppBarLayoutWithVelocity(CoordinatorLayout coordinatorLayout, AppBarLayout appBarLayout, float velocity) {
        try {
            //With reflection, we can call the private method of Behavior that expands the AppBarLayout with specified velocity
            Method animateOffsetTo = getClass().getSuperclass().getDeclaredMethod("animateOffsetTo", CoordinatorLayout.class, AppBarLayout.class, int.class, float.class);
            animateOffsetTo.setAccessible(true);
            animateOffsetTo.invoke(this, coordinatorLayout, appBarLayout, 0, velocity);
        } catch (Exception e) {
            e.printStackTrace();
            //If the reflection fails, we fall back to the public method setExpanded that expands the AppBarLayout with a fixed velocity
            Log.e(TAG, "Failed to get animateOffsetTo method from AppBarLayout.Behavior through reflection. Falling back to setExpanded.");
            appBarLayout.setExpanded(true, true);
        }
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) {
        alreadyFlung = true;
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }
}

หากต้องการใช้ให้ตั้งค่าพฤติกรรมใหม่เป็น AppBarLayout ของคุณ

AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
params.setBehavior(new SmoothScrollBehavior(R.id.nested_scroll_view));

ชั้นเรียนของคุณต้องการ int ใน 'constructor แต่ในโค้ดคุณไม่ได้ส่งอะไรไปยัง constructor
bluesummers

ฉันไม่ดีฉันเพิ่มมัน
Raphael Royer-Rivard

สิ่งนี้ดูดีทำให้การเลื่อนราบรื่น แต่ฉันมีคำถามหนึ่งข้อเป็นไปได้หรือไม่ที่จะให้ NestedScrollView เลื่อนไปที่ AppBarLayout เมื่อ AppBarLayout ไปถึงด้านบนและเมื่อฉันเลื่อนลง AppBarLayout จะปรากฏขึ้นในที่สุดเมื่อ NestedScrollView เลื่อนออกจนหมดแล้ว AppBarLayout จะเริ่มขยาย
Zijian Wang

@ZijianWang โปรดอธิบายฉันว่าคุณหมายถึงอะไรโดย "เลื่อนไปที่ AppBarLayout" และฉันก็ไม่เข้าใจคำถามที่สองของคุณคุณสามารถเขียนซ้ำได้หรือไม่?
Raphael Royer-Rivard

0

คำตอบนี้ช่วยแก้ปัญหานี้ให้ฉันได้ สร้างแบบกำหนดเองAppBarLayout.Behaviorดังนี้:

public final class FlingBehavior extends AppBarLayout.Behavior {
    private static final int TOP_CHILD_FLING_THRESHOLD = 3;
    private boolean isPositive;

    public FlingBehavior() {
    }

    public FlingBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
        if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
            velocityY = velocityY * -1;
        }
        if (target instanceof RecyclerView && velocityY < 0) {
            final RecyclerView recyclerView = (RecyclerView) target;
            final View firstChild = recyclerView.getChildAt(0);
            final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
            consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
        }
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        isPositive = dy > 0;
    }
}

และเพิ่มเข้าไปในAppBarLayoutลักษณะนี้:

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ...
        app:layout_behavior="com.example.test.FlingBehavior">

1
ใช้ไม่ได้กับปัญหาในอีกคำถามคือ RecyclerView ซึ่งไม่ได้ใช้ที่นี่
Felix Edelmann

0

ฉันแค่โพสต์สิ่งนี้ที่นี่เพื่อไม่ให้คนอื่นพลาดในความคิดเห็น คำตอบของJinangทำงานได้อย่างสวยงาม แต่ขอชื่นชม AntPachonเพื่อชี้ให้เห็นวิธีการที่ง่ายกว่ามาก แทนที่จะใช้OnClickวิธีการบนChild of the NestedScrollViewโปรแกรมวิธีที่ดีกว่าคือการตั้งค่าclickable=trueใน xml สำหรับเด็ก

(ใช้ตัวอย่างเดียวกับของ Jinang )

<android.support.v4.widget.NestedScrollView 
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

  <LinearLayout
      android:id="@+id/content_container"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:clickable="true" >                  <!-- new -->

    <!-- Page Content -->

  </LinearLayout>

</android.support.v4.widget.NestedScrollView>

-1

ในโค้ด:https://android.googlesource.com/platform/frameworks/support/+/master/core-ui/java/android/support/v4/widget/NestedScrollView.java#834

       case MotionEvent.ACTION_UP:
            if (mIsBeingDragged) {
                final VelocityTracker velocityTracker = mVelocityTracker;
                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker,
                        mActivePointerId);
                if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                    flingWithNestedDispatch(-initialVelocity);
                } else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,
                        getScrollRange())) {
                    ViewCompat.postInvalidateOnAnimation(this);
                }
            }
            mActivePointerId = INVALID_POINTER;
            endDrag();
            break;

เมื่อฉันใช้การเลื่อนแบบพลิกบน NestedScrollView บางครั้ง "mIsBeingDragged = false" ดังนั้น NestedScrollView จึงไม่จัดส่งเหตุการณ์เหวี่ยง

เมื่อฉันลบif (mIsBeingDragged)คำสั่ง

 case MotionEvent.ACTION_UP:
        //if (mIsBeingDragged) {
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker,
                    mActivePointerId);
            if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                flingWithNestedDispatch(-initialVelocity);
            } else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,
                    getScrollRange())) {
                ViewCompat.postInvalidateOnAnimation(this);
            }
        //}
        mActivePointerId = INVALID_POINTER;
        endDrag();
        break;

จะไม่มีปัญหา แต่ฉันไม่รู้ว่าปัญหาร้ายแรงอื่น ๆ จะเกิดจากอะไร


เพิ่มรายละเอียดเพิ่มเติมเพื่อให้เข้าใจง่ายคำตอบคุณเขียนเมื่อฉันลบ if ...จากที่ที่คุณกำลังพูดถึงเพื่อลบif ?
Devendra Singh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.