উপরে নির্বাচিত আইটেমটি দেখানোর জন্য স্ক্রোল রিসাইক্লারভিউ


215

আমি RecyclerViewশীর্ষে নির্বাচিত আইটেমটি দেখানোর জন্য একটি স্ক্রোল করার কোনও উপায় অনুসন্ধান করছি ।

একটিতে ListViewআমি যে scrollTo(x,y)উপাদানটি কেন্দ্রিক করা দরকার তার শীর্ষস্থান ব্যবহার করে এবং এটি করে সক্ষম হয়েছি ।

কিছুটা এইরকম:

@Override
public void onItemClick(View v, int pos){
    mylistView.scrollTo(0, v.getTop());
}

সমস্যাটি হ'ল পদ্ধতিটি বলার RecyclerViewসময় কোনও ত্রুটি প্রদান করেscrollTo

রিসাইক্লারভিউ কোনও পরম অবস্থানে স্ক্রোলিং সমর্থন করে না

RecyclerViewনির্বাচিত আইটেমটি দেখার শীর্ষে রাখার জন্য আমি কীভাবে স্ক্রোল করব ?

উত্তর:


405

আপনি যদি LinearLayoutManagerবা স্তম্ভিত ব্যবহার করছেন তবে GridLayoutManagerতাদের প্রত্যেকের কাছে একটি স্ক্রোলটপোজনপথবিথঅফসেট পদ্ধতি রয়েছে যা উভয় অবস্থান গ্রহণ করে এবং শুরু থেকে আইটেমের শুরুটির অফসেট উভয়ই গ্রহণ করে RecyclerView, যা দেখে মনে হয় এটি আপনার যা প্রয়োজন তা পূরণ করবে (অফসেটটি 0 এ সেট করে উপরের সাথে সারিবদ্ধ করা উচিত)।

এই ক্ষেত্রে:

//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);

34
যদি কারও একটি পুনর্ব্যবহারযোগ্য ভিউর স্ক্রোল অবস্থান পুনরুদ্ধার করার জন্য এটির প্রয়োজন হয়, স্ক্রোল অবস্থানগুলি কীভাবে সংরক্ষণ করতে হয় (পদ্ধতি স্ক্রোলটোপজিশনবিথঅফসেটের জন্য দুটি যুক্তি): সূচিপত্র = লিনিয়ারলআউটআমনেজ.ফাইন্ডফ্রাস্টভিজিবল আইটেম পজিশন (); ভি = লিনিয়ারলআউটআমনেজ.আর্টচিল্ডএটি (0) দেখুন; int শীর্ষ = (v == নাল)? 0: (v.getTop () - লিনিয়ারলআউটআমনেজ.জেটপ্যাডিংটপ ());
ডোমিনিকএম

স্ক্রোলটোপজিশনটি কল করার সময় আমি এই সম্পর্কে যা মনে করি না তা হল ? যদি বাছাই শ্রোতা পৃথক দর্শনে থাকে তবে কীভাবে পুনর্ব্যবহারযোগ্য ভিউজ (যেটির লেআউট ম্যানেজারটিতে স্ক্রোলটোপজিশন কল করতে পারে তার অ্যাক্সেস রয়েছে) কীভাবে বিজ্ঞপ্তি দেওয়া হবে যে কোনও আইটেম নির্বাচন করা হয়েছে?
ননোস

@ ননোস আপনি প্রথমে আপনি রিসেলারভিউ.সেটলয়েআউটম্যানেজার () এ যে লেআউট ম্যানেজারটি ব্যবহার করেন তা সঞ্চয় করতে পারেন এবং তারপরে সরাসরি এটি অ্যাক্সেস করতে পারেন। এটির মতো: লিনিয়ারলআউটআম্যানাজার llm = নতুন লিনিয়ারলআউটআমনেজার (এটি); mRecyclerView.setLayoutManager (llm); ... (পরে কোডে) ... llm.scrollToPositionWithOffset (2, 20);
নিরাজ

19
আমি যদি শীর্ষে "মসৃণভাবে" স্ক্রোল করতে চাই তবে কী হবে?
টিয়াগো

: @Tiago, আমি এটা নিয়ে খেলেছে, কিন্তু প্রবন্ধ এই 3-অংশ সিরিজ সাহায্য করতে পারে blog.stylingandroid.com/scrolling-recyclerview-part-1
নিরাজ

93

আপনি যদি উল্লম্ব লিনিয়ারলআউট ম্যানেজারের সন্ধান করেন তবে আপনি একটি কাস্টম ব্যবহার করে মসৃণ স্ক্রোলিং অর্জন করতে পারেন LinearSmoothScroller:

import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;

public class SnappingLinearLayoutManager extends LinearLayoutManager {

    public SnappingLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                       int position) {
        RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private class TopSnappedSmoothScroller extends LinearSmoothScroller {
        public TopSnappedSmoothScroller(Context context) {
            super(context);

        }

        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return SnappingLinearLayoutManager.this
                    .computeScrollVectorForPosition(targetPosition);
        }

        @Override
        protected int getVerticalSnapPreference() {
            return SNAP_TO_START;
        }
    }
}

পুনর্ব্যবহারযোগ্য দৃশ্যে লেআউটম্যানেজারের উদাহরণ ব্যবহার করুন এবং তারপরে কল করা পুনর্ব্যবহারযোগ্য দৃশ্যের recyclerView.smoothScrollToPosition(pos);শীর্ষে নির্বাচিত অবস্থানে স্ক্রোলটি মসৃণ করবে calling


1
সত্যিই দরকারী উত্তর! getHorizontalSnapPreference()অনুভূমিক তালিকার জন্য আমি টপস্কেপডমথস্রোলারকেও ওভাররাইড করি ।
জুয়ান সরভিয়া

6
আমি কি ঠিক এই পর্যবেক্ষণে ঠিক আছি যে এটি কেবল কেবল এমন আইটেমগুলির জন্যই কাজ করে যা এখনও বাকিগুলি পূরণ করার জন্য তাদের / নীচে যথেষ্ট রয়েছে RecyclerView? - নির্বিশেষে এই শেষ আইটেমের জন্য কাজ বলে মনে হচ্ছে না: কোনটি বলতে হয় শুধুমাত্র স্ক্রল পর্যন্ত আইটেমটি নীচে দৃশ্যমান হয় কিন্তু এটি সব পথ সরাতে আপ নেই। এটিকে কীভাবে অর্জন করা যায় তার কোনও ধারণা? (আমি কাস্টম প্যাডিং সেট করে এটির চারপাশে কাজ করেছি তবে এটি সত্যিকার অর্থে সঠিক মনে হচ্ছে না ...)SNAP_TO_STARTRecyclerViewRecyclerView
ডেভিড.মিহোলা


আইটেমটি প্রদর্শিত না হয়ে ফোকাস হয়ে যায়, আইটেম দর্শনের জন্য আমার দৃষ্টি আকর্ষণযোগ্য।
ওয়াইএলএস

1
@ david.mihola আপনি একটি 'সঠিক' পথ খুঁজে পেয়েছেন? আমি আমার recyclerview সেট কাস্টম প্যাডিং করেছি কিন্তু আমি কিছু অদ্ভুত সমস্যা হচ্ছে ...
bernardo.g

52

// স্ক্রোল আইটেম পোস্ট

linearLayoutManager.scrollToPositionWithOffset(pos, 0);

7
এটি সহজেই করার কোনও উপায় আছে?
আশকান


1
@ মার্কবুকাইক্যা আমি এটি আগে খুঁজে পেয়েছি। আপনার মনোযোগের জন্য থ্যাঙ্কস ডিউড
আশকান

28

আপনার শুধু কল করা দরকার recyclerview.scrollToPosition(position) । সেটা ঠিক আছে!

আপনি যদি এটি অ্যাডাপ্টারে কল করতে চান, কেবলমাত্র আপনার অ্যাডাপ্টারের কাছে পুনর্ব্যবহারযোগ্য দর্শন বা ক্রিয়াকলাপ বা খণ্ডের মধ্যে যেমন পুনর্ব্যবহারযোগ্য রয়েছে তার পদ্ধতিটি প্রয়োগের পরিবর্তে যাক getRecyclerview() তাদের মধ্যে।

আমি আশা করি এটি আপনাকে সহায়তা করতে পারে।


2
এটি আমার জন্য কাজ করেছে - পুনর্ব্যবহারযোগ্য.স্ক্রোলটোপজিশন (0); আমাকে শীর্ষে রাখো
রে হান্টার

2
কাজ করছে না যে আপনি রৈখিক লেআউটআউট ম্যানেজ.সেকারলটোপোসনবিথঅফসেট ব্যবহার করতে হবে (পোস্ট, 0);
অনিল উগলে

@ আনিল উগালে এটি বাজে কথা। অবশ্যই এটি কাজ করে। আপনি একটি পুনর্ব্যবহারযোগ্য ভিউয়ের জন্য যে কোনও লেআউটম্যানেজার ব্যবহার করতে পারেন। আপনি যখন স্ক্রোল করতে চান তখন কেন আপনার এটি সম্পর্কে যত্ন নেওয়া উচিত? আমি মনে করি আপনি কিছু ভুল করছেন। রিসাইক্লারভিউ.স্ক্রোলটোপজিশন (পজিশন) হ'ল একটি সুবিধা পদ্ধতি যা লেআউট ম্যানেজ.সেকারলটোপজিশন (অবস্থান) বলে।
অবিশ্বাস্য জানুয়ারী

1
@ ইনক্রেডিবলজান এটি সমস্ত ক্ষেত্রে কাজ করে না, লেআউট ম্যানেজার সাধারণত আপনার তথ্যের জন্য কোনওভাবেই স্ক্রোলিংয়ের জন্য দায়বদ্ধ।
মোহাম্মদ

11

গতি নিয়ন্ত্রকের সাথে একই

public class SmoothScrollLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 110f;
private Context mContext;

public SmoothScrollLinearLayoutManager(Context context,int orientation, boolean reverseLayout) {
    super(context,orientation,reverseLayout);
    mContext = context;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                   int position) {
    RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()){
        //This controls the direction in which smoothScroll looks for your view
        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return new PointF(0, 1);
        }

        //This returns the milliseconds it takes to scroll one pixel.
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
        }
    };
    smoothScroller.setTargetPosition(position);
    startSmoothScroll(smoothScroller);
}


private class TopSnappedSmoothScroller extends LinearSmoothScroller {
    public TopSnappedSmoothScroller(Context context) {
        super(context);

    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return SmoothScrollLinearLayoutManager.this
                .computeScrollVectorForPosition(targetPosition);
    }

    @Override
    protected int getVerticalSnapPreference() {
        return SNAP_TO_START;
    }
}
}

8

আমার জন্য দুর্দান্ত কাজ করে দেখুন!

একটি পরিবর্তনশীল তৈরি করুন private static int displayedposition = 0;

আপনার ক্রিয়াকলাপে এখন আপনার পুনর্ব্যক্তিকালীন অবস্থানের জন্য।

myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                LinearLayoutManager llm = (LinearLayoutManager) myRecyclerView.getLayoutManager();


                displayedposition = llm.findFirstVisibleItemPosition();


            }
        });

আপনার বক্তব্যটি যেখানে প্রদর্শন করা হয়েছে সেখানে যেখানে এটি রাখতে চান সেখানে এই বিবৃতিটি রাখুন।

LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager();
        llm.scrollToPositionWithOffset(displayedposition , youList.size());

ঠিক আছে, এটি আমার পক্ষে ভাল কাজ করেছে \ o /


7

এই পদ্ধতিটি কেবল কল করুন:

((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);

পরিবর্তে:

recyclerView.scrollToPosition(yourItemPosition);

"পরিবর্তে"? ডিস্টও "স্ক্রোলটোপজিশন" উল্লেখ করেনি। তিনি যদি এটি ব্যবহার করতেন তবে কোনও সমস্যা হত না। হিসাবে স্ক্রোলটোপোজিস্টেশন ()।
অবিশ্বাস্য জানুয়ারী

1
আশ্চর্যজনকভাবে যথেষ্ট, স্ক্রোলটোপজিশনবিহীন অফসেটটি ব্যবহার করা আমার এবং পুনর্ব্যবহারযোগ্য পর্যালোচনা.স্রোকল টোপজিশনটির পক্ষে কাজ করে না। যদিও, আমি আমিরকে পুনর্ব্যবহারযোগ্য দর্শনটিকে রিসাইক্লারভিউতে পরিবর্তন করার জন্য অনুরোধ করব, কারণ এটি একটি ধারণা দেয় যে পদ্ধতিগুলি স্থির, এবং সেগুলি নয়।
মোহিত

6

বোতাম ক্লিক করা রিসাইক্লারভিউ রিফ্রেশ করার পরে স্ক্রোল অবস্থান পুনরুদ্ধার করতে আমি কি করেছি:

if (linearLayoutManager != null) {

    index = linearLayoutManager.findFirstVisibleItemPosition();
    View v = linearLayoutManager.getChildAt(0);
    top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop());
    Log.d("TAG", "visible position " + " " + index);
}

else{
    index = 0;
}

linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.scrollToPositionWithOffset(index, top);

লিনিয়ারলআউটআম্যানাজার অবজেক্ট তৈরি করার আগে উপরের থেকে প্রথম দৃশ্যমান আইটেমটির অফসেট পাওয়া এবং এটি ইনস্ট্যান্ট করার পরে লিনিয়ারলআউটম্যানেজার অবজেক্টের স্ক্রোলটপোজিওনঅফসেট বলা হয়েছিল।


6

কেন আমি সেরা উত্তরটি খুঁজে পেলাম না কেন এটি সত্যিই সহজ।

recyclerView.smoothScrollToPosition(position);

কোনও ত্রুটি নেই

অ্যানিমেশন তৈরি করে


আপনি এটিকে ক্রিয়াকলাপ বা অ্যাডাপ্টারে রাখবেন কোথায়?
আর্নল্ড ব্রাউন

3

নির্দিষ্ট অবস্থানে স্ক্রোল করুন
এবং এটি আমাকে অনেক সাহায্য করেছিল। ক্লিক শ্রোতার দ্বারা আপনি আপনার অ্যাডাপ্টারে অবস্থান পেতে পারেন

layoutmanager.scrollToPosition(int position);

3
If you want to scroll automatic without show scroll motion then you need to write following code:

**=> mRecyclerView.getLayoutManager().scrollToPosition(position);**

If you want to display scroll motion then you need to add following code.
=>Step 1: You need to declare SmoothScroller.

RecyclerView.SmoothScroller smoothScroller = new
                LinearSmoothScroller(this.getApplicationContext()) {
                    @Override
                    protected int getVerticalSnapPreference() {
                        return LinearSmoothScroller.SNAP_TO_START;
                    }
                };

=>step 2: You need to add this code any event you want to perform scroll to specific position.
=>First you need to set target position to SmoothScroller.

**smoothScroller.setTargetPosition(position);**

=>Then you need to set SmoothScroller to LayoutManager.
                        **mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);**

3

উত্তরের কোনওটিই শীর্ষে সর্বশেষ আইটেম (গুলি) কীভাবে প্রদর্শন করবেন তা ব্যাখ্যা করে না। সুতরাং, উত্তরগুলি কেবলমাত্র সেই আইটেমগুলির জন্যই কাজ করে যা এখনও বাকি বাগুলি পূরণ করার জন্য তাদের উপরে বা নীচে পর্যাপ্ত আইটেম রয়েছে RecyclerView। উদাহরণস্বরূপ, যদি 59 টি উপাদান থাকে এবং 56-তম উপাদানটি নির্বাচিত হয় তবে এটি নীচের চিত্রের মতো শীর্ষে থাকা উচিত:

পুনর্ব্যবহারযোগ্য - উপাদান 56 নির্বাচন করা হয়েছে আমরা ব্যবহার করে সেই ক্ষেত্রে হ্যান্ডেল করতে পারে linearLayoutManager.scrollToPositionWithOffset(pos, 0)মধ্যে এবং অতিরিক্ত যুক্তিবিজ্ঞান Adapterএর RecyclerView(যদি শেষ আইটেম নয় প্রোফাইল তাহলে এর মানে হল আছে পর্যাপ্ত স্থান ভরাট শেষ আইটেম নীচে একটি কাস্টম মার্জিন যোগ করে - RecyclerView)। কাস্টম মার্জিনটি মূল দেখার উচ্চতা এবং আইটেমের উচ্চতার মধ্যে পার্থক্য হতে পারে। সুতরাং, আপনার Adapterজন্য RecyclerViewনিম্নলিখিত হিসাবে চেহারা হবে:

...
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    ...

    int bottomHeight = 0;
    int itemHeight = holder.itemView.getMeasuredHeight();
    // if it's the last item then add a bottom margin that is enough to bring it to the top
    if (position == mDataSet.length - 1) {
        bottomHeight = Math.max(0, mRootView.getMeasuredHeight() - itemHeight);
    }
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)holder.itemView.getLayoutParams();
    params.setMargins(0, 0, params.rightMargin, bottomHeight);
    holder.itemView.setLayoutParams(params);

    ...
} 
...

2

আমার ক্ষেত্রে আমার RecyclerViewমতো একটি প্যাডিং শীর্ষ রয়েছে

<android.support.v7.widget.RecyclerView
     ...
     android:paddingTop="100dp"
     android:clipToPadding="false"
/>

তারপরে একটি আইটেম শীর্ষে স্ক্রোল করার জন্য, আমার প্রয়োজন

recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());

1

যদি আপনার LayoutManagerহয় তবে LinearLayoutManagerআপনি scrollToPositionWithOffset(position,0);এটি ব্যবহার করেন এবং এটি আপনার আইটেমটিকে তালিকার প্রথম দৃশ্যমান আইটেম তৈরি করবে। অন্যথা, আপনি ব্যবহার করতে পারেন smoothScrollToPositionউপরRecyclerView সরাসরি।

আমি নীচের কোডটি ব্যবহার করে শেষ করেছি।

 RecyclerView.LayoutManager layoutManager = mainList.getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager) {
            // Scroll to item and make it the first visible item of the list.
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(position, 0);
        } else {
            mainList.smoothScrollToPosition(position);
        }

-2

আমি নীচে কোডটি কোনও আইটেমটি (এই দেখুন) শীর্ষে মসৃণ-স্ক্রোল করতে ব্যবহার করি।
এটি বিভিন্ন উচ্চতার ভিউ সহ গ্রিডলাউট ম্যানেজারের জন্যও কাজ করে:

View firstView = mRecyclerView.getChildAt(0);
int toY = firstView.getTop();
int firstPosition = mRecyclerView.getChildAdapterPosition(firstView);
View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition);
int fromY = thisView.getTop();

mRecyclerView.smoothScrollBy(0, fromY - toY);

দ্রুত সমাধানের জন্য যথেষ্ট ভাল কাজ করে মনে হচ্ছে।


1
এর মান কী thisPosition?
pRaNaY

আপনি যে অবস্থানটিতে স্ক্রোলটি মসৃণ করতে চান তা এটি
জান রাবে

কোনও গণনা ছাড়াই কেন স্মুথস্ক্রোলটোপজিশন (ইন পজিশন) ব্যবহার করবেন না? আপনি যেখান থেকে শুরু করেছেন তাতে কিছু আসে যায় না, তাই না?
অবিশ্বাস্য জানুয়ারী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.