Yas*_*maz 2 android android-recyclerview
我有一个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<CustomAdapter.ViewHolder> {
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<String> mItems;
public CustomAdapter(Context context, ArrayList<String> 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
那么,我该怎样避免呢?(在Android Android Observable-ScrollView中截取的截图和代码)

您必须在某处存储项目的状态,并在onBindViewHolder()调用时恢复它们.
在RecyclerView中,视图数与项目数不同; 它通常不到那个.
将首先创建项目1-10的视图,并且如果其中一些项目(例如,项目1-4)被滚动,则为项目1-4创建的视图将被重用/绑定到项目11-14,依此类推.(我只是编了数字.它们可能因情况而异)
换句话说,视图创建一次,并且多次绑定.
在你的情况下,
您需要跟踪所有项目状态,并使视图反映出来 onBindViewHolder()
编辑:
这些是您在滚动并单击按钮时发生的情况.(为简单起见,我将项目数量限制为10,并假设屏幕上最多可以绘制3个项目.)
最初的状态是这样的:
在这里,onCreateViewHolder()被称为4次; 它将布局资源扩展到视图中,并为视图创建视图持有者.也onBindViewHolder()被称为4次; 设置视图的文本
然后你点击第1项,
dark color视图#1的按钮颜色现在变暗.
并向下滚动一点,
View #1 - (scrolled out, not visible, dark color)View #4 - text:"Item 4", original color现在,视图#1已滚动.视图#4变为可见,onBindViewHolder()并将视图的文本设置为"项目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));
}
Run Code Online (Sandbox Code Playgroud)
并且您的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);
}
Run Code Online (Sandbox Code Playgroud)
它只是更改视图的按钮颜色,而不关心单击哪个项目.因此,无法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);
}
Run Code Online (Sandbox Code Playgroud)
无论何时onBindViewHolder()调用,它都会检查是否单击了该项并设置了按钮颜色.click()方法还会检查单击了哪个项目.
| 归档时间: |
|
| 查看次数: |
4744 次 |
| 最近记录: |