RecyclerView的项目未正确显示

时间:2016-04-24 14:03:16

标签: java android android-recyclerview

当用户点击onBindViewHolder时,RecyclerView.Adapter<SearchAdapter.ViewHolder> cardview我的@Override public void onBindViewHolder(final ViewHolder viewHolder, final int position) { viewHolder.card.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (viewHolder.content_layout.getVisibility() == View.VISIBLE) { viewHolder.content_layout.setVisibility(View.GONE); viewHolder.address.setMaxLines(2); viewHolder.attribute.setMaxLines(2); } else { viewHolder.content_layout.setVisibility(View.VISIBLE); viewHolder.address.setMaxLines(8); viewHolder.attribute.setMaxLines(8); } } }); ... } 按钮变为可见。但是当我滚动recyclerview时,其他一些项目按钮也显示为可见。为什么会这样?

这是我的代码:

var recipes = [String: PFFile]()
var valueToPass: String!
var valuePassed: String!
var appetizer = [String]()

var images = [String: UIImage]()

override func viewDidLoad() {
    super.viewDidLoad()

    let query = PFQuery(className: "Appetizers")
    query.orderByAscending("recipe")
    query.findObjectsInBackgroundWithBlock { (objects, error) in

        guard error == nil, let objects = objects else {
            print(error)
            return
        }

        for object in objects {

            // ... Appetizer Name

            let appetizerName = object.objectForKey("appetizer") as! String
            self.name.text = self.valuePassed

            // ... Recipe

            var recipes = [String: String]()

            let recipeFile = object["recipe"] as! PFFile

            do {

                let recipeData = try recipeFile.getData()
                let recipe = String(data: recipeData , encoding:NSUTF8StringEncoding)!
                print(recipe)  // recipe is now a string you can store or display

                self.myTextView.text = recipe

            } catch {
                print("something went wrong")
            }


            // ... Image

            let imageFile = object["imageFiles"] as!PFFile
            imageFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in

                if error == nil {

                    let data = imageData

                } else {

                    print(error)

                }

                if let data = imageData {

                    self.images[appetizerName] = UIImage(data: data)
                    self.imageView.image = self.images[self.valuePassed]

                }
            })

        }

    }

}

4 个答案:

答案 0 :(得分:11)

一旦开始向下滚动列表,您的视图就会被回收。这意味着先前膨胀的ViewHolder(在onCreateViewHolder中创建的一些)将被重用 因此,您需要做的是记住点击的位置(例如通过SparseBooleanArray)并检查onBindViewHolder视图是否应该可见(之前点击过)。

您可以在this StackOverflow帖子

中找到SparseBooleanArray的基本用法示例

答案 1 :(得分:6)

“其他”可见项按钮是使用在回调中修改的相同视图的按钮。因为视图持有者(和视图)被回收:

  • 它们应该只存储每次将视图符号绑定到某个位置时可以检索的信息。

  • 视图状态中可能更改的任何内容都应在onBindViewHolder()

  • 中刷新

在你的情况下,你应该在其他地方存储“被选中”重置onBindViewHolder()中的可见性和最大限度(不仅仅是在回调中)

答案 2 :(得分:5)

好主意是在Recycler视图中创建一个包含一个项目所需数据的类对象,同时添加一个布尔isItemWasClicked并在onBindViewHolder()内检查此布尔值并使按钮可见或不可见。 例如:

public class OneItemOfList{
    int priceToDisplay;
    String name;
    String date;
    boolean wasClicked;
}

public class YourAdapter extends RecyclerView.Adapter<OneItemOfList.ViewHolder> {
ArrayList<OneItemOfList> items;
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    viewHolder.view.setText(items.get(position).name);
    if (items.get(position).wasClicked)
        viewHolder.button.setVisible(View.VISIBLE);
    else
        viewHolder.button.setVisible(View.GONE);
    viewHolder.view2.setOnClickListener(...
        OnClick(...){
            items.get(position).wasClicked = !items.get(position).wasClicked;
        });
}
...
}

答案 3 :(得分:2)

创建一个数组,例如布尔数组,当点击每个位置时,在数组的相同位置设置true。并在onBindViewHolder中检查该数组[position]是否为true,将该项设置为if。