Android लेआउट: क्षैतिज पुनरावर्तन के अंदर एक क्षैतिज पुनरावर्तन के अंदर स्क्रॉल व्यवहार के साथ दृश्यदर्शी के अंदर




android-layout android-recyclerview (4)

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

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

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

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

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

गतिविधि xml लेआउट:

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

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

वर्टीकलीक्रॉसक्राइक्लर व्यू का कोड नीचे है:

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);
    }
}

प्रयत्न

public OuterRecyclerViewAdapter(List<Item> items) {
    //Constructor stuff
    viewPool = new RecyclerView.RecycledViewPool();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //Create viewHolder etc
    holder.innerRecyclerView.setRecycledViewPool(viewPool);

}

भीतर का पुनर्नवीनीकरण एक ही दृश्य का उपयोग करेगा और यह चिकना होगा


मेरा सुझाव है कि आप Google ऐप की तरह टुकड़ों में क्षैतिज recyclerview जोड़ सकते हैं


यदि कोई अभी भी देख रहा है, तो यह कोशिश करें:

private val Y_BUFFER = 10
private var preX = 0f
private var preY = 0f

mView.rv.addOnItemTouchListener(object : RecyclerView.OnItemTouchListener {
        override fun onTouchEvent(p0: RecyclerView, p1: MotionEvent) {

            }

        override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                when (e.action) {
                    MotionEvent.ACTION_DOWN -> rv.parent.requestDisallowInterceptTouchEvent(true)
                    MotionEvent.ACTION_MOVE -> {
                        if (Math.abs(e.x - preX) > Math.abs(e.y - preY)) {
                            rv.parent.requestDisallowInterceptTouchEvent(true)
                        } else if (Math.abs(e.y - preY) > Y_BUFFER) {
                            rv.parent.requestDisallowInterceptTouchEvent(false)
                        }

                    }
                }
                preX = e.x
                preY = e.y
                return false
            }

            override fun onRequestDisallowInterceptTouchEvent(p0: Boolean) {
            }
        })

यह जाँचता है कि वर्तमान में क्षैतिज स्क्रॉल कर रहा है तो माता-पिता को घटना को नियंत्रित करने की अनुमति न दें





android-appbarlayout