簡體   English   中英

RecyclerView和AdapterView,無法顯示項目

[英]RecyclerView and AdapterView, fails to show items

我正在做一些簡單的示例,以作為指導,等等。我有一個帶有自己的適配器的RecyclerView。 這些項目是數據模型,帶有文本和圖像。 ViewHolder,除了包含相應的視圖外,還添加了一個布爾值以控制圖像是否可見。

當我單擊時,例如在第一項中,圖像消失(或者如果再次單擊,則顯示)。

問題是,如果單擊(例如第一個元素),圖像將按預期消失,但是在滾動並且回收者加載不可見的新元素時,一個元素會突然與隱藏圖像一起出現。

稍微調試一下,我看到在加載元素時,取決於布爾值會顯示為true,理論上應該為false。

我不知道發生了什么,因為列表中的元素是不同的。

PS:就像我說的那樣,代碼真的很容易,所以不要指望偉大的事情。

主要活動:

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

        recyclerView = (RecyclerView) findViewById(R.id.recycler);

        List<Person> personList = new ArrayList<>();
        personList.add(new Person ("User1"));
        personList.add(new Person ("User2"));
        personList.add(new Person ("User3"));
        personList.add(new Person ("User4"));
        personList.add(new Person ("User5"));
        personList.add(new Person ("User6"));
        personList.add(new Person ("User7"));
        personList.add(new Person ("User8"));
        personList.add(new Person ("User9"));
        personList.add(new Person ("User10"));
        personList.add(new Person ("User11"));
        personList.add(new Person ("User12"));
        personList.add(new Person ("User13"));
        personList.add(new Person ("User14"));
        personList.add(new Person ("User15"));
        personList.add(new Person ("User16"));
        personList.add(new Person ("User17"));
        personList.add(new Person ("User18"));
        personList.add(new Person ("User19"));
        personList.add(new Person ("User20"));
        personList.add(new Person ("User22"));
        personList.add(new Person ("User23"));


        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        CustomImageAdapter adapter = new CustomImageAdapter(personList);
        recyclerView.setAdapter(adapter);

適配器:

public class CustomImageAdapter extends RecyclerView.Adapter<CustomImageAdapter.ViewHolder> {

    private List<Person> personList;

    public CustomImageAdapter(List<Person> personList) {
        this.personList = personList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.image_person, parent, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {

        Person person = personList.get(position);
        holder.name.setText(person.getName());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!holder.imageHide) {
                    holder.image.setVisibility(View.INVISIBLE);

                } else {
                    holder.image.setVisibility(View.VISIBLE);
                }
                holder.imageHide = !holder.imageHide;
            }
        });
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        ImageView image;
        boolean imageHide = false;


        public ViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.name);
            image = (ImageView) itemView.findViewById(R.id.image);
            imageHide = false;
        }
    }
}

數據模型:(僅是一個隱秘的峰值)

public class Person {
    private String name;
    private String image;


    public Person(String name) {
        this.name = name;
    }
    ....
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="30dp"
        android:layout_height="30dp"
        app:srcCompat="@mipmap/ic_launcher"/>
</LinearLayout>

幾個圖像作為示例:

在此處輸入圖片說明

在此處輸入圖片說明

ViewHolder類旨在用於快速訪問“ View”相關項目,例如具有這種性質的textviews或imageViews。

當內容需要基於對象模型是動態的時,則對象模型需要驅動可見性模式。 在viewholder類內沒有嵌套的布爾值。

這樣想吧。 回收者視圖回收(n)個視圖。

--View 1(顯示人1)在Viewholder 1中可見

--View 2(顯示人2)布爾值在Viewholder 1中可見

--View 3(顯示人3)布爾值在Viewholder 1中可見

點擊查看1

-查看1-保存布爾值false“圖像不可見”

點擊后當前視圖

--View 1(顯示人1)在Viewholder 1中不可見的布爾值

--View 2(顯示人2)布爾值在Viewholder 1中可見

--View 3(顯示人3)布爾值在Viewholder 1中可見

現在您滾動回收站

視圖1不在屏幕上,並在下一個屏幕上回收,因為“人4”現在在觀察者模式中保留了布爾值

--View 2(顯示人2)布爾值在Viewholder 2中可見

--View 3(顯示人員3)在Viewholder 3中可見

--View 1(顯示第4個人)布爾值在Viewholder 1中不可見

因此,要糾正此問題:只需像這樣修改代碼:

public class Person {
private String name;
private String image;
private boolean isVisible;

public boolean getIsVisible(){
     return isVisible;
}
public void setIsVisible(boolean value){
    isVisible = value;
}


public Person(String name) {
    this.name = name;
}
....

}

然后像這樣修改您的適配器:

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {

    final Person person = personList.get(position);
    holder.name.setText(person.getName());
    holder.image.setVisibility(person.getIsVisibility() ? VISIBLE : INVISIBLE);
    onItemClick(holder.root, person, position);
}

   /*///////////////////////////////////////////////////////////////
// CLICK LISTENERS
*////////////////////////////////////////////////////////////////
private void onItemClick(final LinearLayout root, final Person model, final int position){
    root.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            person.setIsVisible(!person.getIsVisible());
            root.findViewById(YOUR_IMAGE_ID).setVisibility(person.getIsVisible() ? VISIBLE : INVISIBLE);
             //or if you prefer to not findViewById, you can just update person boolean and call
            //notifyDataSetChanged();

        }

    });

}

然后,如果您選擇執行findViewById路由,則將根ID添加到您的XML文件和viewholder類中(建議使用更有效的方法,然后進行通知)

您可能需要考慮的另一件事是解釋如何處理適配器外部的喀噠聲。 通常,如果我不進行數據綁定,則傾向於使用接口。 將其添加到適配器的底部。

 public interface ItemSelectedListener {
    void personList_onItemClick(View view, int position, final Person person);
    void personList_onItemLongClick(View view, int position, final Person person);

}

然后在構造函數中,需要ItemSelectedListener並將其存儲在適配器類中。 然后,您可以修改onClick處理程序來執行

  private void onItemClick(final LinearLayout root, final Person person, final int position){
    root.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(mItemSelectedListener != null){
                mItemSelectedListener.personList_onClick(v, position, person);

            }

        }

    });

}

當然,請重復上述操作以進行長按。

   private void onItemLongClick(final LinearLayout root, final Person person, final int position){
    root.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if(mItemSelectedListener != null){
                mItemSelectedListener.personList_onItemLongClick(v, position, model);

            }

            return false;

        }

    });

}

並且當然也可以將用於長時間單擊的偵聽器添加到您的bindview中

@Override
    public void onBindViewHolder(final ViewHolder holder, int position) {

        final Person person = personList.get(position);
        holder.name.setText(person.getName());
        holder.image.setVisibility(person.getIsVisibility() ? VISIBLE : INVISIBLE);
        onItemClick(holder.root, person, position);
        onItemLongClick(holder.root, person, position);
    }

您的代碼看起來還不錯,但可能與RecyclerViews的工作方式有關。 我認為這是發生在您身上的,因為您僅更改了持有人的價值,而持有人正在被回收以保存不同的數據項。

您是否可以嘗試將boolean imageHide到Person類,然后在onClick中更改person類中的該布爾值並設置圖像的可見性。 然后在onBind中使用一些邏輯來檢查該人是否應該隱藏或可見圖像。

您需要在onBindViewHolder上添加一個驗證,如下所示:

holder.image.setVisibility(holder.imageHide ?View.VISIBLE:View.INVISIBLE);

問候。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM