【问题标题】:onBindViewHolder increase position onClickListeneronBindViewHolder 增加位置 onClickListener
【发布时间】:2019-07-09 14:16:04
【问题描述】:

我有一个带有两个按钮 NextPrevious 和一个 textview 的活动,我想在每次点击时更新 textview 内容下一个或返回 例如,如果我单击 Next,则 textview 应该显示下一个位置的内容,反之亦然。 我认为我应该使用循环,但是当我尝试这样做时它给了我一个错误,当我将 1 添加到位置 (i+1) 它工作但它只给了我第二个位置,我想获得所有位置不仅是第二个。我真的不知道我的问题是否清楚,希望是:)

onBindViewHolder

@Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, @SuppressLint("RecyclerView") final int i) {

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

            String nextContent = listItems.get(i).getContent();
            String previousContent = listItems.get(i).getContent();
            Intent intent = new Intent(v.getContext(), Main2Activity.class);
            intent.putExtra("next", nextContent);
            intent.putExtra("prev", previousContent);
            v.getContext().startActivity(intent);

        }
    });
}

Main2Activity

btnNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemTextView.setText(nextContent);
        }
    });

btnPrev.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemTextView.setText(prevContent);
        }
    });

【问题讨论】:

    标签: java android


    【解决方案1】:

    onBindViewHolder 方法中设置点击监听器是不好的做法

    为什么?因为每次回收视图时都会调用 onBindViewHolder 以在屏幕上显示新内容。假设您有一个包含 1000 个元素的列表,其中 10 个元素在屏幕上可见。

    您将其滚动到最后 => 然后 onBindViewHolder 将被调用 990 次 => 990 个点击侦听器集。

    您还希望避开 onBindViewHolder() 中的昂贵操作,因为您的滚动速度可能会减慢。

    更多提示:

    Recyclerview(Getting item on Recyclerview)

    【讨论】:

    • 这并不试图回答所提出的问题。如果你想给出提示,你可以使用 cmets
    【解决方案2】:

    循环不是这里的答案,循环是为了使某些事情自动化。这是一个事件(用户交互),因此不合适。

    你可能想要的算法基本上如下:

    • 用户点击了一个项目
    • 找出项目索引
    • 增加索引
    • 找到具有该索引的项目(通过询问列表)
    • 如果存在,请对其进行处理

    但是,您发布的代码中的问题是您的“下一个内容”始终是当前项目。因此,您需要进行以下更改(但要注意边界):

    String nextContent = listItems.get(i+1).getContent();
    String previousContent = listItems.get(i-1).getContent();
    

    你当前的代码没有使用循环,所以 onBind 方法应该为i 的每个值调用一次,所以它不应该总是第二项


    在您的 cmets 之后,您会看到与列表无关的按钮,所以现在您需要做的是,每次单击 RV 或 Next/Prev 中的项目时,您都会存储正确的索引(当您无权访问i)

    在活动中:

    private int currentTextItem = 0;
    
    public void setCurrentTextItem(int i) {
        currentTextItem = i;
        //the dots here will be how you get the text from the item
        //   probably recyclerView.findViewHolderForAdapterPosition(pos) 
        myTextView.setText( ... );
    }
    

    在您看来持有人代码:

    myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //(You should have some kind of call back from viewholder to activity)
            activity.setCurrentTextItem(i);
        }
    });
    

    然后你的下一个/上一个:

    btnNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setCurrentTextItem(currentTextItem + 1);
        }
    });
    
    btnPrev.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setCurrentTextItem(currentTextItem - 1);
        }
    });
    

    【讨论】:

    • 我已经尝试过了,然后当我点击下一步按钮时,它会显示来自位置 1 的内容。我还有30多个职位想通过。当我尝试 (i+30) 时,它直接进入第 30 位,但这不是解决方案。我想逐个位置 (i+1) 然后 (i+2) 然后 (i+3)... 每次单击“下一步”按钮。希望你能理解我的兄弟:)
    • 如何在 onBind 方法中使用循环?我已经尝试过了,它给了我一个错误!
    • 请不要叫我兄弟。首先,列表中的 btnNext 是否仅作为一行?还是与回收商分开?还是每行都有一个下一步按钮?
    • 我有一个包含 3 列(id、title、content)的 Sqlite 数据库。应用程序中有一个从 db 获取标题的 recyclerview,它运行良好,我想要做的是创建一个带有 textview 和两个按钮的活动,正如我之前提到的,所以当我点击 recyclerview 中的某个项目时,它应该给我来自 db 的内容数据并将其设置为 textview 并且我想通过内容数据而不需要返回并从 rv 中选择另一个项目!
    • 这是我正在做的项目stackoverflow.com/questions/56933555/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多