android एंड्रॉइड लेआउट: स्क्रॉल बिहेविर्स के साथ व्यूपार्जर के अंदर वर्टिकल रीसाइक्लर्विव के अंदर क्षैतिज पुनर्चक्रण




android-layout android-recyclerview (3)

मैं थोड़ा देर हो चुकी हूं लेकिन यह एक ही समस्या का सामना करने वाले अन्य लोगों के लिए काम करेगा

 mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                int action = e.getAction();
               // Toast.makeText(getActivity(),"HERE",Toast.LENGTH_SHORT).show();
                switch (action) {
                    case MotionEvent.ACTION_POINTER_UP:
                        rv.getParent().requestDisallowInterceptTouchEvent(true);

                        break;
                }
                return false;
            }

यह वह ऐप है जिसे मैं नीचे मैप किए गए सभी तत्वों के साथ बनाने की कोशिश कर रहा हूं:

सबकुछ काम करता है, हालांकि, मैं आंतरिक क्षैतिज पुनर्नवीनीकरण चाहता हूं कि किसी लंबवत स्क्रॉल को कैप्चर न करें। सभी लंबवत स्क्रॉल को बाहरी लंबवत रीसाइक्लर्विव की ओर जाना चाहिए, क्षैतिज नहीं, ताकि वर्टिकल स्क्रॉल टूलबार के स्क्रॉल के अनुसार दृश्य से बाहर निकलने की अनुमति दे।

जब मैंने रीसाइक्लिंगव्यू के "स्ट्रॉबेरी प्लांट" भाग पर अपनी उंगली डाली और स्क्रॉल किया, तो यह टूलबार को स्क्रॉल करें:

अगर मैं क्षैतिज स्क्रॉलव्यू पर अपनी उंगली डालता हूं और स्क्रॉल करता हूं, तो यह टूलबार को स्क्रॉल नहीं करता है।

अब तक मेरा एक्सएमएल लेआउट कोड निम्नलिखित है।

गतिविधि एक्सएमएल लेआउट:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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:id="@+id/fragment_container"
    android:clipChildren="false">

    <android.support.design.widget.CoordinatorLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"
        >

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            style="@style/CustomTabLayout"
            />

    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />

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

</FrameLayout>

"फल" खंड xml लेआउट (जो टुकड़े के लिए कोड है - खंड को उपरोक्त चित्र में लेबल किया गया है):

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

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:visibility="gone"
        android:layout_centerInParent="true"
        android:indeterminate="true"/>

<!--    <android.support.v7.widget.RecyclerView-->
    <com.example.simon.customshapes.VerticallyScrollRecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

मैंने VerticallyScrollRecyclerView नामक एक कस्टम क्लास का उपयोग किया है जो व्यू ग्रुप में हैंडलिंग टच इवेंट्स के Google उदाहरण का पालन करता है। इसका उद्देश्य सभी लंबवत स्क्रॉल ईवेंट को रोकना और उपभोग करना है ताकि वह टूलबार में / बाहर स्क्रॉल कर सके: http://developer.android.com/training/gestures/viewgroup.html

VerticallyScrollRecyclerView के लिए कोड नीचे है:

public class VerticallyScrollRecyclerView extends RecyclerView {

    public VerticallyScrollRecyclerView(Context context) {
        super(context);
    }

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

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    ViewConfiguration vc = ViewConfiguration.get(this.getContext());
    private int mTouchSlop = vc.getScaledTouchSlop();
    private boolean mIsScrolling;
    private float startY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            mIsScrolling = false;
            startY = ev.getY();
            return super.onInterceptTouchEvent(ev); // Do not intercept touch event, let the child handle it
        }
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                Log.e("VRecView", "its moving");
                if (mIsScrolling) {
                    // We're currently scrolling, so yes, intercept the
                    // touch event!
                    return true;
                }
                // If the user has dragged her finger horizontally more than
                // the touch slop, start the scroll
                // left as an exercise for the reader
                final float yDiff = calculateDistanceY(ev.getY());
                Log.e("yDiff ", ""+yDiff);
                // Touch slop should be calculated using ViewConfiguration
                // constants.
                if (Math.abs(yDiff) > 5) {
                    // Start scrolling!
                    Log.e("Scroll", "we are scrolling vertically");
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }


    private float calculateDistanceY(float endY) {
        return startY - endY;
    }

}

"पसंदीदा" लेआउट जो लंबवत पुनर्चक्रण के भीतर पुनर्नवीनीकरण है:

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

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/white"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Favourite"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="16dp"
        android:id="@+id/header_fav"/>

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@+id/header_fav"
        android:id="@+id/recyclerview_fav">
    </android.support.v7.widget.RecyclerView>

</RelativeLayout>

यह मुझे थोड़ी देर के लिए परेशान कर रहा है और मैं समाधान के साथ आने में कामयाब नहीं रहा हूं। किसी को इस समस्या को हल पता है?

सही जवाब के लिए ग्रिफिंडर को 5 अंक और निश्चित रूप से, एसओ पर प्रतिष्ठा अंक।


परीक्षण समाधान, एक कस्टम NestedScrollView() उपयोग करें।

कोड:

public class CustomNestedScrollView extends NestedScrollView {
    public CustomNestedScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
         // Explicitly call computeScroll() to make the Scroller compute itself
            computeScroll();
        }
        return super.onInterceptTouchEvent(ev);
    }
}

परीक्षण समाधान:

आपको केवल mInnerRecycler.setNestedScrollingEnabled(false); को कॉल mInnerRecycler.setNestedScrollingEnabled(false); आपके आंतरिक RecyclerView पर


स्पष्टीकरण :

RecyclerView ने NestedScrollingChild इंटरफेस को लागू करने के माध्यम से API 21 में पेश नेस्टेड स्क्रॉलिंग के लिए समर्थन किया है। यह एक मूल्यवान विशेषता है जब आपके पास स्क्रॉलिंग दृश्य होता है जो एक ही दिशा में स्क्रॉल करता है और आप ध्यान केंद्रित करते समय केवल आंतरिक View को स्क्रॉल करना चाहते हैं।

किसी भी मामले में, डिफ़ॉल्ट कॉल द्वारा RecyclerView.setNestedScrollingEnabled(true); प्रारंभ करते समय खुद पर। अब, समस्या पर वापस जाएं, क्योंकि आपके दोनों RecyclerView AppBarBehavior एक ही AppBarBehavior के AppBarBehavior , जिसमें AppBarBehavior , CoordinateLayout को यह तय करना होगा कि जब आप अपने आंतरिक RecyclerView AppBarBehavior से स्क्रॉल करते हैं तो किस स्क्रॉल का जवाब देना होगा; जब आपका आंतरिक RecyclerView की नेस्टेड स्क्रॉलिंग सक्षम होती है, तो उसे स्क्रॉलिंग फोकस मिल जाता है और CoordinateLayout बाहरी RecyclerView स्क्रॉलिंग पर इसकी स्क्रॉलिंग का जवाब देना चुनता है। बात यह है कि, चूंकि आपके आंतरिक RecyclerView व्यू लंबवत स्क्रॉल नहीं करते हैं, इसलिए कोई लंबवत स्क्रॉल परिवर्तन नहीं होता है ( CoordinateLayout के दृष्टिकोण से), और यदि कोई बदलाव नहीं होता है, तो AppBarLayout या तो नहीं बदलता है।

आपके मामले में, क्योंकि आपके आंतरिक RecyclerView एक अलग दिशा में स्क्रॉल कर रहे हैं, आप इसे अक्षम कर सकते हैं, इस प्रकार CoordinateLayout को इसके स्क्रॉलिंग को नजरअंदाज करने और बाहरी RecyclerView स्क्रॉलिंग का जवाब देने का कारण बनता है।


नोटिस :

एक्सएमएल विशेषता android:nestedScrollingEnabled="boolean" का उद्देश्य android:nestedScrollingEnabled="boolean" के उपयोग के लिए नहीं है, और android:nestedScrollingEnabled="false" का उपयोग करने का प्रयास है android:nestedScrollingEnabled="false" परिणामस्वरूप java.lang.NullPointerException होगा, कम से कम अब के लिए, आपके पास होगा कोड में ऐसा करने के लिए।





android-appbarlayout