簡體   English   中英

獲取Infinite RecyclerView的中心可見項值

[英]Get the center visible item value of Infinite RecyclerView

圖片 我通過將適配器計數為 Integer.MAX 創建了一個圓形回收器視圖。現在,我需要突出顯示圖像中的中心回收器項目。請幫助我!

如果你想使用horizo​​ntalscrollview(動態創建項目)而不是recyclerview。

創建你的父布局

 <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true">

            <LinearLayout
                android:layout_alignParentBottom="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"/>

        </HorizontalScrollView>

將您的子項目膨脹到父布局。

     LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                for (int i = 0; i < list.size(); i++) {
          // inflate child element
          final LinearLayout titleRow = (LinearLayout) inflater.inflate(R.layout.item_gallery, fragmentGalleryScrollLl, false);
                    final CircleImageView shapeImageView = (CircleImageView) titleRow.findViewById(R.id.item_gallery_iv);

                    shapeImageView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {

                            scrollItem(titleRow);


                        }
                    });
                    fragmentGalleryScrollLl.addView(titleRow);

                }

單擊項目時使用此方法。

 private void scrollItem(LinearLayout titleRow) {
        int scrollX = (titleRow.getLeft() - (fragmentGalleryScrollSv.getWidth() / 2)) + (titleRow.getWidth() / 2);
        fragmentGalleryScrollSv.smoothScrollTo(scrollX, 0);
    }
By using center indicator(textview) in the layout and addOnScrollListner we can achieve this
please refer the following example

在 xml 中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
    android:layout_width="wrap_content"
    android:text="↓"
    android:id="@+id/centerIndicator"
    android:textSize="24sp"
    android:textStyle="bold"
    android:visibility="visible"
    android:textColor="@color/theme_yellow"
    android:layout_centerHorizontal="true"
    android:layout_height="wrap_content"
    android:layout_marginTop="27dp"
    android:background="@android:color/transparent"
    />
<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:id="@+id/list"
    android:clipToPadding="false"
    android:divider="@android:color/transparent"
    android:layout_height="wrap_content"/>

</RelativeLayout>

在活動/片段中:

public class Sample extends Fragment {
    RecyclerView listView;
    ArrayList<String>mWeekDaysList=new ArrayList<>();
    LinearLayoutManager mlinearLayoutManagerForDateList;
    DateAdapter mDateAdapter;
    TimeListAdapter mtimeAdapter;
    private int mCenterPivot;
    private boolean mAutoSet = true;
    Activity mactivity;
    public NigaichiNiralFrag() {
        // Required empty public constructor
    }
    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view= inflater.inflate(R.layout.fragment_nigaichi_niral, container, false);
mactivity=getActivity();
        mWeekDaysList.add("Sunday");
        mWeekDaysList.add("Monday");
        mWeekDaysList.add("Tuesday");
        mWeekDaysList.add("Wednesday");
        mWeekDaysList.add("Thursday");
        mWeekDaysList.add("Friday");
        mWeekDaysList.add("Saturday");

        listView = (RecyclerView) view.findViewById(R.id.list);
        mlinearLayoutManagerForDateList = new LinearLayoutManager(mactivity);
mlinearLayoutManagerForDateList.setOrientation(LinearLayoutManager.HORIZONTAL);
        listView.setLayoutManager(mlinearLayoutManagerForDateList);
        final TextView mCenterIndicator = (TextView) view.findViewById(R.id.centerIndicator);
        final int itemWidth = (int) getResources().getDimension(R.dimen.flexible_space_image_height) ;
        mlinearLayoutManagerForDateList.scrollToPosition(Integer.MAX_VALUE / 2);        
        mDateAdapter=new DateAdapter(mWeekDaysList);
        listView.setAdapter(mDateAdapter);
        mCenterIndicator.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {

                int center = ( mCenterIndicator.getLeft() + mCenterIndicator.getRight() ) / 2 ;
                int padding =  center - itemWidth / 2; //Assuming both left and right padding needed are the same
                listView.setPadding(5,0,5,0);
                mCenterPivot = center;
                listView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                        super.onScrollStateChanged(recyclerView, newState);
                        LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager();
                        if( mCenterPivot == 0 ) {

                            // Default pivot , Its a bit inaccurate .
                            // Better pass the center pivot as your Center Indicator view's
                            // calculated center on it OnGlobalLayoutListener event
                            mCenterPivot = lm.getOrientation() == LinearLayoutManager.HORIZONTAL ? ( recyclerView.getLeft() + recyclerView.getRight() ) : ( recyclerView.getTop() + recyclerView.getBottom() );
                        }
                        if( !mAutoSet ) {

                            if( newState == RecyclerView.SCROLL_STATE_IDLE ) {
                                //ScrollStoppped

                                View view = findCenterView(lm);//get the view nearest to center
                                //view.setBackgroundColor(Color.RED);

                                int position = recyclerView.getChildAdapterPosition(view) % mWeekDaysList.size();
                                Log.d("isideScroll",mWeekDaysList.get(position));
                                mDateAdapter.setSelecteditem(position);
                                int viewCenter = lm.getOrientation() == LinearLayoutManager.HORIZONTAL ? ( view.getLeft() + view.getRight() )/2 :( view.getTop() + view.getBottom() )/2;
                                //compute scroll from center
                                int scrollNeeded = viewCenter - mCenterPivot; // Add or subtract any offsets you need here

                                if( lm.getOrientation() == LinearLayoutManager.HORIZONTAL ) {

                                    recyclerView.smoothScrollBy(scrollNeeded, 0);
                                }
                                else
                                {
                                    recyclerView.smoothScrollBy(0, (int) (scrollNeeded));

                                }
                                mAutoSet =true;
                            }
                        }
                        if( newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING ){

                            mAutoSet =false;
                        }
                    }

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

            }
        });
        return returnView;
    }
    private void scrollToCenter(View v) {
        int itemToScroll = listView.getChildAdapterPosition(v);
        int centerOfScreen = listView.getWidth() / 2 - v.getWidth() / 2;
        //v.setBackgroundColor(Color.RED);
        mlinearLayoutManagerForDateList.scrollToPositionWithOffset(itemToScroll, centerOfScreen);
    }
   private View findCenterView(LinearLayoutManager lm) {

    int minDistance = 0;
    View view = null;
    View returnView = null;
    boolean notFound = true;

    for(int i = lm.findFirstVisibleItemPosition(); i <= lm.findLastVisibleItemPosition() && notFound ; i++ ) {

        view=lm.findViewByPosition(i);

        int center = lm.getOrientation() == LinearLayoutManager.HORIZONTAL ? ( view.getLeft() + view.getRight() )/ 2 : ( view.getTop() + view.getBottom() )/ 2;
        int leastDifference = Math.abs(mCenterPivot - center);

        if( leastDifference <= minDistance || i == lm.findFirstVisibleItemPosition())
        {
            minDistance = leastDifference;
            returnView=view;
        }
        else
        {
            notFound=false;

        }
    }
    return returnView;
}
}

適配器:

public class DateAdapter extends  RecyclerView.Adapter<DateAdapter.ReviewHolder>  {
    ArrayList<String> mData;
    private int selectedItem = -1;
    int pos=0;
    public DateAdapter(ArrayList<String> data){
        mData=data;
    }

    @Override
    public ReviewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        View v= LayoutInflater.from(context).inflate(R.layout.item_horz,parent,false);
        return new DateAdapter.ReviewHolder(v);
    }

    @Override
    public void onBindViewHolder(ReviewHolder holder, int position) {
        pos=position;
        position = position % mData.size();
        holder.tvName.setText(mData.get(position));
        holder.tvName.setGravity(Gravity.CENTER);

        if (position == selectedItem) {
            Log.d("CenterPosition", "center" + position);
            holder.tvName.setTextColor(Color.RED);
            holder.tvName.setTextSize(20);
            holder.tvName.setBackgroundColor(Color.parseColor("#fccd00"));

        } else {
            holder.tvName.setTextColor(Color.WHITE);
            holder.tvName.setTextSize(16);
            holder.tvName.setBackgroundColor(Color.BLACK);
        }
    }

    @Override
    public int getItemCount() {
        // return mData.size();
        return Integer.MAX_VALUE;
    }

    public class ReviewHolder extends RecyclerView.ViewHolder {

        protected TextView tvName;
        View container;

        public ReviewHolder(View itemView) {
            super(itemView);
            container=itemView;
            tvName= (TextView) itemView.findViewById(R.id.text);
        }
    }
    public void setSelecteditem(int selecteditem) {
        Log.d("POSITION",String.valueOf(selecteditem));
        this.selectedItem = selecteditem;
        notifyDataSetChanged();
    }

}

item_horz.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:layout_width="151dp"
        android:id="@+id/wrapper"
        android:background="@color/white"
    android:orientation="horizontal"
        android:layout_height="50dp">
    <LinearLayout
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="@color/black">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textSize="20sp"
            android:id="@+id/text"
            android:textColor="@color/white"
            android:text="21"
            android:gravity="center"
            />
    </LinearLayout>
    </LinearLayout>

希望這對你們有幫助..

在 BindView 中,您可以檢查適配器的中間位置並為該特定持有者應用圖像邏輯。

 onBindViewHolder(View holder, int postion){
if(position == getItemCount() / 2) 
{ //Write image logic for holder
}}

滾動停止時回調以獲取中心項目位置

import android.content.Context
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class RecyclerCenterItemFinder(
    private val context: Context,
    private val layoutManager: LinearLayoutManager,
    private val callback: (Int) -> Unit,
    private val controlState: Int = RecyclerView.SCROLL_STATE_IDLE
) :
    RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        if (controlState == ALL_STATES || newState == controlState) {
            val firstVisible = layoutManager.findFirstVisibleItemPosition()
            val lastVisible = layoutManager.findLastVisibleItemPosition()
            val itemsCount = lastVisible - firstVisible + 1
            val screenCenter: Int = context.resources.displayMetrics.widthPixels / 2
            var minCenterOffset = Int.MAX_VALUE
            var middleItemIndex = 0
            for (index in 0 until itemsCount) {
                val listItem = layoutManager.getChildAt(index) ?: return
                val topOffset = listItem.top
                val bottomOffset = listItem.bottom
                val centerOffset =
                    Math.abs(topOffset - screenCenter) + Math.abs(bottomOffset - screenCenter)
                if (minCenterOffset > centerOffset) {
                    minCenterOffset = centerOffset
                    middleItemIndex = index + firstVisible
                }
            }
            callback(middleItemIndex)
        }
    }

    companion object {
        const val ALL_STATES = 10
    }
}

recycler.addOnScrollListener(RecyclerCenterItemFinder(requireContext(),
                recycler.layoutManager,
                { centerItemPosition ->
                    // do something
                }
            ))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM