当前位置: 首页 > 知识库问答 >
问题:

RecyclerView-如何在滚动期间突出显示中心可见项

阴福
2023-03-14

我需要像这样的回收视图:

它应该做到:

>

  • 每次显示7项(完成)

    将回收视图居中放置在中心可见项上(完成)

    当我向右/向左滚动时,中心项目将被“突出显示”(按钮被选中)

    当我点击一个按钮时,它将以一个平滑的圆点居中(需要帮助)

    我使用SnapHelper类将RecyclerView集中在中心项上(我检索中心可见项,将最近的子项放在屏幕中心)

    我的适配器:

    public class RvTrendsGraphAdapter extends RecyclerView.Adapter<RvTrendsGraphAdapter.ViewHolder> {
    
        private float deviceWidth;
        private float itemWidth;
    
        private List<RvTrendsGraphModel> models;
        private Context context;
    
        public RvTrendsGraphAdapter(Context context, List<RvTrendsGraphModel> models) {
            this.models = models;
            this.context = context;
        }
    
        private Context getContext() {
            return context;
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
            @BindView(R.id.rv_trends_graph_layout) PercentRelativeLayout rootLayout;
            @BindView(R.id.rv_trends_graph_layout_superiore) PercentRelativeLayout layoutSuperiore;
            @BindView(R.id.rv_trends_graph_layout_inferiore) RelativeLayout layoutInferiore;
            @BindView(R.id.rv_trends_graph_vertical_progressbar) ProgressBar verticalProgressBar;
            @BindView(R.id.rv_trends_graph_button) Button timeLapseButton;
    
            public ViewHolder(View itemView) {
                super(itemView);
                ButterKnife.bind(this, itemView);
            }
        }
    
    
        @Override
        public RvTrendsGraphAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Context context = parent.getContext();
            LayoutInflater inflater = LayoutInflater.from(context);
            View view = inflater.inflate(R.layout.recycler_trends_graph, parent, false);
    
            // Set the width to show 7 elements
            DisplayMetrics displayMetrics = new DisplayMetrics();
            WindowManager windowmanager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
            windowmanager.getDefaultDisplay().getMetrics(displayMetrics);
            deviceWidth = displayMetrics.widthPixels;
            float progressBarWidth = getContext().getResources().getDimension(R.dimen.picker_time_lapse_progressbar_width);
            itemWidth = ((deviceWidth + progressBarWidth) / 8f + 1f);
            view.getLayoutParams().width = (int) itemWidth;
    
            return new ViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(RvTrendsGraphAdapter.ViewHolder viewHolder, int position) {
            RvTrendsGraphModel model = models.get(position);
    
            PercentRelativeLayout rootLayout = viewHolder.rootLayout;
            ProgressBar verticalProgressBar = viewHolder.verticalProgressBar;
            Button timeLapseButton = viewHolder.timeLapseButton;
    
            verticalProgressBar.setProgress(model.getProgress());
            setTimeLapseButton(timeLapseButton, model.getTimeLapseValue());
        }
    
        @Override
        public int getItemCount() {
            return models.size();
        }
    
        public RvTrendsGraphModel getItem(int position) {
            return models.get(position);
        }
    
        /* UTILS */
    
        private void setTimeLapseButton(Button button, String text) {
            //button.setSelected(false);
            button.setText(text);
        }
    
    }
    

    设置回收器视图:

    mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    mRecyclerView.setLayoutManager(mLayoutManager);
    
    SnapHelper snapHelper = new LinearSnapHelper();
    snapHelper.attachToRecyclerView(mRecyclerView);
    

    填充回收器视图:

    list = new ArrayList<>();
    /* Create foo list... */
    list.add(new RvTrendsGraphModel(75, String.valueOf(list.size())));
    list.add(new RvTrendsGraphModel(33, String.valueOf(list.size())));
    // ...
    
    adapter = new RvTrendsGraphAdapter(getActivity(), list);
    mRecyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    
    mRecyclerView.smoothScrollToPosition(list.size() - 1);
    

    滚动管理:

    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    // Get adapter position of the central item
                    PercentRelativeLayout root = (PercentRelativeLayout) mRecyclerView.findChildViewUnder(centralX, 0);
                    pos = mRecyclerView.getChildAdapterPosition(root);
    
                    // first try (very bad)
                    if (lastPos != pos) {
                        pos = lastPos;
                        adapter.notifyDataSetChanged();
                    }
    
                    // second try (I cannot call notifyitemchanged during the scroll
                    if () {
                        final int pos = mRecyclerView.getChildAdapterPosition(root);
                        adapter.getItem(pos).setCentered(true);
                        adapter.notifyItemChanged(pos);
                    }
                }
            });
    

    项目布局:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.percent.PercentRelativeLayout
        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:id="@+id/rv_trends_graph_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="MissingPrefix">
    
        <android.support.percent.PercentRelativeLayout
            android:id="@+id/rv_trends_graph_layout_superiore"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_heightPercent="75%">
    
            <ProgressBar
                android:id="@+id/rv_trends_graph_vertical_progressbar"
                style="@style/Widget.ProgressBar.Vertical"
                android:layout_width="@dimen/picker_time_lapse_progressbar_width"
                android:layout_height="match_parent"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:progress="50"
                />
        </android.support.percent.PercentRelativeLayout>
    
        <RelativeLayout
            android:id="@+id/rv_trends_graph_layout_inferiore"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_below="@+id/rv_trends_graph_layout_superiore"
            app:layout_heightPercent="25%">
    
            <Button
                android:id="@+id/rv_trends_graph_button"
                fontPath="fonts/Roboto-Light.ttf"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:background="@drawable/picker_time_lapse_selector"
                android:minHeight="0dp"
                android:minWidth="0dp"
                android:textAllCaps="true"
                android:textColor="@color/picker_time_lapse_text_color_selector"
                android:textSize="@dimen/text_size_medium"
                tools:ignore="ContentDescription"
                tools:text="16"/>
    
        </RelativeLayout>
    
    </android.support.percent.PercentRelativeLayout>
    
  • 共有1个答案

    萧亦
    2023-03-14

    希望这有帮助-

    请注意,这是一个黑客解决方案,尤其是在滚动上突出显示。此外,我还没有介绍任何业绩。你可能应该检查一下。我还将timeLapseButton更改为TextView,因为在按钮上更改背景会折叠其他布局属性。

    如果你不喜欢黑客的解决方案,你可以查看一些图表库。

    例:)https://github.com/PhilJay/MPAndroidChart

    适配器类

    public interface TimeLapseButtonClickListener {
        void onClick(int position);
    }
    
    private TimeLapseButtonClickListener timeLapseButtonListener;
    
    public void setTimeLapseButtonClickListener(TimeLapseButtonClickListener listener) {
        this.timeLapseButtonListener = listener;
    }
    
    private void setTimeLapseButton(Button button, String text, final int position) {
        button.setText(text);
    
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                this.timeLapseButtonListener.onClick(position);
            }
        });
    }
    

    有recyclerView的活动或片段

    ...
    
    private int prevCenterPos; // Keep track the previous pos to dehighlight
    
    ...
    
    // Click and smooth scroll to get clicked item in the middle
    adapter.setListener(new RvTrendsGraphAdapter.TimeLapseButtonClickListener() {
        @Override
        public void onClick(int position) {
            View view = mRecyclerView.getLayoutManager().findViewByPosition(position);
            int middle = mRecyclerView.getWidth() / 2;
            mRecyclerView.smoothScrollBy(view.getLeft() - middle, 0, new AccelerateDecelerateInterpolator());
        }
    });
    
    // Highlight view in the middle on scroll
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
    
            int center = mRecyclerView.getWidth() / 2;
            View centerView = mRecyclerView.findChildViewUnder(center, mRecyclerView.getTop());
            int centerPos = mRecyclerView.getChildAdapterPosition(centerView);
    
            if (prevCenterPos != centerPos) {
                // dehighlight the previously highlighted view
                View prevView = mRecyclerView.getLayoutManager().findViewByPosition(prevCenterPos);
                if (prevView != null) {
                    View button = prevView.findViewById(R.id.rv_trends_graph_button);
                    int white = ContextCompat.getColor(context, R.color.white);
                    button.setBackgroundColor(white);
                }
    
                // highlight view in the middle 
                if (centerView != null) {
                    View button = centerView.findViewById(R.id.rv_trends_graph_button);
                    int highlightColor = ContextCompat.getColor(context, R.color.colorAccent);
                    button.setBackgroundColor(highlightColor);
                }
    
                prevCenterPos = centerPos;
            }
        }
    });
    

     类似资料:
    • 问题内容: 我有一个弹出列表,其中包含子s 的垂直列表。我添加了向上/向下键盘导航来更改当前突出显示的哪个孩子。 现在,如果我按下向下键的次数足够多,则突出显示的项目将不再可见。如果滚动视图,则向上键也会发生相同的情况。 在React中自动将孩子滚动到视图中的正确方法是什么? 问题答案: 我假设您具有某种组件和某种组件。我在一个项目中执行此操作的方式是让该项目知道它是否处于活动状态。该项目将要求列

    • 我使用http://svn.openstreetmap.org/applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/demo.java中的代码为我的swing应用程序创建并运行一个映射。 我添加了几个MapMarkerDot来指示地图中的一些点,并使用如何从JMapViewer世界地图中获取鼠标单击位置来识别是否选

    • 问题内容: 我需要添加一个可以列出an元素的位置,并且我发现有一种更新更好的显示列表的方法- 。 我的问题是如何在我的应用程序中实现这一点。我发现我需要使用,但是我不太了解如何正确实现整个过程。 如果你想知道,我指的是这个的文档的例子,这是我一直在读。 编辑: 更新我的代码后,它说它无法解析该符号: 所以我以为我把它放错了地方(很可能),实际上我把它放到Adapter类的末尾,就在Method之后

    • 这就是我想要的: 如上图所示,我想在上画一条中心线,然后在滚动时获得中心项(以及向左或向右移动) 以下是我尝试画一个水平的: 有没有办法知道哪个项目移动到了回收视图的中心?如何将向左或向右滚动一个位置? 更新:我尝试使用滚动侦听器来获得中间位置,但它不能作为一个方面。 并得到结果: 我只想在蓝色上更改选中的项目(使文本变为白色)

    • 我一直在寻找一个适当的API来做我需要做的事情,我几乎可以肯定的是,必须有一个API。但我找不到。 提前致谢

    • 如何更改日历视图特定日期的颜色?我正在创建一个简单的应用程序,可以在日历上添加事件,我想突出显示有事件的日期。有人能告诉我怎么做吗?如果不可能,请给我一些其他的建议。