当前位置:  开发笔记 > Android > 正文

Android RecyclerView按钮滚动时多次单击效果

如何解决《AndroidRecyclerView按钮滚动时多次单击效果》经验,为你挑选了1个好方法。

我有一个RecyclerView列出文本和按钮.如果我单击按钮,Toast文本显示位置,按钮颜色将更改为#343434.当我点击一个按钮时这很好但是如果我循环我的RecyclerView另一个按钮颜色改变而不是点击,只有背景颜色改变.

正如您在下面看到的那样:首先我点击第1项并Toast显示文本,按钮背景更改.然后我循环下来,第15项的按钮背景正在改变.最后,我向上滚动到第一个位置项目1的按钮颜色仍然是原始颜色,并且项目4的按钮背景颜色被更改.

所以这是我的代码块:

public class HandleTouchRecyclerViewActivity extends BaseActivity implements ObservableScrollViewCallbacks {
private static final String TAG = HandleTouchRecyclerViewActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_handletouchrecyclerview);

    ObservableRecyclerView recyclerView = (ObservableRecyclerView) findViewById(R.id.scroll);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);
    recyclerView.setScrollViewCallbacks(this);
    recyclerView.setAdapter(new CustomAdapter(this, getDummyData()));
}

@Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
    Log.v(TAG, "onScrollChanged: scrollY: " + scrollY + " firstScroll: " + firstScroll + " dragging: " + dragging);
}

@Override
public void onDownMotionEvent() {
    Log.v(TAG, "onDownMotionEvent");
}

@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
    Log.v(TAG, "onUpOrCancelMotionEvent: scrollState: " + scrollState);
}

public static class CustomAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private LayoutInflater mInflater;
    private ArrayList mItems;

    public CustomAdapter(Context context, ArrayList items) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mItems = items;
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(mContext, mInflater.inflate(R.layout.list_item_handletouch, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        viewHolder.textView.setText(mItems.get(position));
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        Context context;

        public ViewHolder(Context context, View view) {
            super(view);
            this.context = context;
            this.textView = (TextView) view.findViewById(android.R.id.text1);
            view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    click(getLayoutPosition() + 1,v);

                    v.setBackgroundColor(Color.parseColor("#343434"))

                }
            });
        }

        private void click(int i,View view) {
            String message = "Button " + i + " is clicked";
            view.setBackgroundColor(Color.parseColor("#343434"));
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

            Log.v(TAG, "click: " + message);
        }
    }
}

}

那么,我该怎样避免呢?(在Android Android Observable-ScrollView中截取的截图和代码) 关于我的过程



1> nexus5x..:

您必须在某处存储项目的状态,并在onBindViewHolder()调用时恢复它们.

在RecyclerView中,视图数与项目数不同; 它通常不到那个.

将首先创建项目1-10的视图,并且如果其中一些项目(例如,项目1-4)被滚动,则为项目1-4创建的视图将被重用/绑定到项目11-14,依此类推.(我只是编了数字.它们可能因情况而异)

换句话说,视图创建一次,并且多次绑定.

在你的情况下,

向下滚动时,首先创建并绑定到项目1的视图将被回收并绑定到项目15.

当你再次向上滚动时,视图(项目15,暗按钮)被滚动并绑定到项目4

第1项绑定到以前用于绑定到其他项目的其他视图,该视图具有原始按钮颜色.

您需要跟踪所有项目状态,并使视图反映出来 onBindViewHolder()

编辑:

这些是您在滚动并单击按钮时发生的情况.(为简单起见,我将项目数量限制为10,并假设屏幕上最多可以绘制3个项目.)

最初的状态是这样的:

查看#1 - 文本:"项目1",原始颜色

查看#2 - 文本:"项目2",原始颜色

查看#3 - 文本:"项目3",原始颜色

查看#4 - (这是预先创建的,以备将来使用,尚未显示)

在这里,onCreateViewHolder()被称为4次; 它将布局资源扩展到视图中,并为视图创建视图持有者.也onBindViewHolder()被称为4次; 设置视图的文本

然后你点击第1项,

查看#1 - 文字:"第1项", dark color

查看#2 - 文本:"项目2",原始颜色

查看#3 - 文本:"项目3",原始颜色

查看#4 - (尚未显示,原始颜色)

视图#1的按钮颜色现在变暗.

并向下滚动一点,

View #1 - (scrolled out, not visible, dark color)

查看#2 - 文本:"项目2",原始颜色

查看#3 - 文本:"项目3",原始颜色

View #4 - text:"Item 4", original color

现在,视图#1已滚动.视图#4变为可见,onBindViewHolder()并将视图的文本设置为"项目4".

滚动更多,

查看#2 - 文本:"项目2",原始颜色

查看#3 - 文本:"项目3",原始颜色

查看#4 - 文本:"项目4",原始颜色

View #1 - text:"Item 5", dark color (now this view is recycled)

看最后一行; 没有新创建的视图,并且onBindViewHolder()调用它将View#1的文本设置为"Item 5".但是,您的实现onBindViewHolder()不会设置按钮颜色.

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    viewHolder.textView.setText(mItems.get(position));
}

并且您的click()方法不会跟踪单击的项目.

private void click(int i,View view) {
    String message = "Button " + i + " is clicked";
    view.setBackgroundColor(Color.parseColor("#343434"))
    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

    Log.v(TAG, "click: " + message);
}

它只是更改视图的按钮颜色,而不关心单击哪个项目.因此,无法onBindViewHolder()检查此项是否已被点击过.

这是一个可能的解决方案:

// declare an array to check which item has been clicked
private boolean[] mIsItemClicked = new boolean[mItems.size()];

private void initClickedItems() {
    for (int i = 0; i < mIsItemClicked; ++i) {
        mIsItemClicked = false;
    }
}

private void click(int i,View view) {
    mIsItemClicked[i] = !mIsItemClicked[i]; // toggle
    String message = "Button " + i + " is clicked";
    view.setBackgroundColor(Color.parseColor("#343434"))
    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

    Log.v(TAG, "click: " + message);
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    viewHolder.textView.setText(mItems.get(position));
    int buttonColor;
    if (mIsItemClicked[i])
        buttonColor = Color.parseColor("#343434");
    else
        buttonColor = Color.parseColor("#ffffff");  // whatever the original color is
    viewHolder.itemView.findViewById(R.id.button).setBackgroundColor(buttonColor);
}

无论何时onBindViewHolder()调用,它都会检查是否单击了该项并设置了按钮颜色.click()方法还会检查单击了哪个项目.

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有