android recyclerview setVisibility View.GONE 仍然占据space

android recyclerview setVisibility View.GONE still occupies space

我只想在我的回收站视图中列出不喜欢的项目。我在 MainActivity 的 rv 中有一个完整的项目列表(这里没有设置可见性)。我可以通过单击图像按钮为每个项目设置喜欢或不喜欢。 MainActivity 显示了显示图像按钮喜欢与否的项目(卡片视图)的完整列表。如果项目被喜欢,这将作为单独的条目存储在 firebase db 中,位于 Likes with item key (firebase key .push) 下,而不是 Items 下。 (在 firebase db 中我有用户、项目、喜欢)。

这是我的子activity 代码,DislikedItemsActivity,在这里我想通过对喜欢的项目使用 setVisibility(View.GONE) 来仅显示不喜欢的项目。 View.GONE 项目之间的 space 仍然存在(尽管这些卡片视图是空的)。

mRecyclerView = (RecyclerView) findViewById(R.id.rvItemList);
mRecyclerView .setHasFixedSize(true);

final LinearLayoutManager linearLayoutManager = new 
LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true); 

mRecyclerView.setLayoutManager(linearLayoutManager);

final FirebaseRecyclerAdapter<Item, MainActivity.ItemViewHolder> 
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Item, 
MainActivity.ItemViewHolder>(
            Item.class,
            R.layout.list_item,
            MainActivity.ItemViewHolder.class,
            mDatabase

    ) {
        @Override
        protected void populateViewHolder(final MainActivity.ItemViewHolder viewHolder, final Item model, final int position) {

            final String itemKey = getRef(position).getKey();

            mDatabaseItemsLiked.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

        // if item is not liked, thus no user set in db ( I want to see only items that are liked in my recyclerview)
                    if (!dataSnapshot.child(itemKey).hasChild(mAuth.getCurrentUser().getUid())) {

                        viewHolder.mView.setVisibility(View.VISIBLE);

                        viewHolder.itemNameSetup(model.getItemName());
                        viewHolder.mView.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                                Intent itemSheetIntent = new Intent(DislikedItemsActivity.this, ItemSheetActivity.class);
                                adatlapIntent.putExtra("item_key", itemKey);
                                startActivity(itemSheetIntent);
                            }
                        });

                    } else {

                        viewHolder.mView.setVisibility(View.GONE);

                        mRecyclerView.getAdapter().notifyItemRemoved(position); //this puts together the visible items, but when scrolling, it gets messed up

        }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.e(TAG, databaseError.toString());
                }
            });
        }

        @Override
        public void onBindViewHolder(MainActivity.TermekViewHolder viewHolder, int position) {
            super.onBindViewHolder(viewHolder, position);

        }
    };
    mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}

我寻找了许多解决方案,例如 onBindViewHolder、notifyDataChanged、将边距设置为 0、将 xml 中的布局大小设置为 wrap_content。我能得到的最好的是让不喜欢的项目没有 space 和 mRecyclerView.getAdapter().notifyItemRemoved(position);,但是向后滚动列表整个 rv 变得混乱(重复条目,空spaces,无序列表)。

我不知道如何在新的 activity 中从 MainActivity rv 的完整项目列表中仅列出不喜欢的项目?我上面的代码只显示不喜欢的项目,但只有在我滚动到列表末尾时,如果我向后滚动,rv 才会变得混乱。我在 onBindViewHolder 中记录了视图(18 个项目)的位置,首先它按顺序计算所有项目(17、16、15、14 ... 0),但是从列表末尾向后滚动位置从 0 跳到 4,就像 7 次(总是改变多少次)然后它与项目 5,6 相同,直到项目 17(它们的所有位置在滚动期间在 onBindViewHolder 中显示 7 或 8 次,即 5,5,5,5,6,6,6 ,6) 且仅用于向后滚动和向后移动期间 rv 仅显示不喜欢的项目或空视图或不喜欢项目的重复条目。

我的xml:

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/hatter"
tools:context="com.example.user.itemlist.ItemsLikedActivity">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rvItemList"
    >
</android.support.v7.widget.RecyclerView>

(不知道怎么加图)当不喜欢的列表出现时,它显示第一个项目(cardview占满屏幕),当我开始滚动列表时(从第一个可见的项目到下一个可见的项目) item) 如果有space(item1 vis and next vis item is 4), 重新排列,我可以看到下一个visible item(item4) 移动到1. visible item,然后列表的其余部分排列好了,直到我开始向后滚动,然后它用 spaces 和复式重新排列 rv。该列表来回移动直到两端(这是完整项目列表的长度,而不仅仅是不喜欢的项目),但是可见的项目都搞砸了。

您可以尝试将喜欢的项目存储在 boolean array 中,稍后在 populateViewHolder 中检查项目是否有喜欢或设置可见性。

我会这样做:

  1. 在您的 class 声明中:

private boolean [] itemLiked;

  1. 在你的构造函数中:

this.itemLiked = new boolean [arrayOfAllItems.size]

  1. 点击事件:

itemLiked[position] = true; //Where position is row position

  1. onBindViewholder 或在您的情况下 populateViewHolder:

    if (!itemLiked[position]) {
    viewHolder.mView.setVisibility(View.GONE); }

希望对你有所帮助,祝你好运!

已编辑 我不明白你到底想做什么,这就是为什么我给你留下两种情况的代码。 案例 1. 标记和取消标记行。 案例2.保存到数据库或删除。

继续完整代码

Activity XML 添加 RecyclerView:

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

自定义行布局:

<TextView
    android:id="@+id/question_tv"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="5"
    android:text="QUESTION"/>

<ImageButton
    android:id="@+id/like"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:src="@android:drawable/ic_input_add"
    android:background="@android:color/transparent"
    android:layout_marginRight="4dp"/>

<ImageButton
    android:id="@+id/dislike"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:src="@android:drawable/ic_delete"
    android:background="@android:color/transparent"
    android:layout_marginRight="4dp"/>

制作模型class:

public class SomeModel {
    private String question;

    public SomeModel(String question) {
        this.question = question;
    }
    public String getQuestion() {
        return question;
    }
}

制作适配器 Class:

public class SomeAdapter extends RecyclerView.Adapter {
private ArrayList<SomeModel> arrayList;
private boolean [] item_has_like, item_hase_vote;

public SomeAdapter(ArrayList<SomeModel> arrayList) {
    this.arrayList = arrayList;
    this.item_has_like = new boolean[arrayList.size()];
    this.item_hase_vote = new boolean[arrayList.size()];
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    MyViewHolder myViewHolder = null;
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    View view = layoutInflater.inflate(R.layout.draw_row, parent, false);
    myViewHolder = new MyViewHolder(view);
    return myViewHolder;
}

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

    final MyViewHolder myViewHolder = (SomeAdapter.MyViewHolder)holder;
    final SomeModel item = arrayList.get(position);
    int backGround;
   /**In background you can save whateveryou need, example:
    * backGround= R.drawable.some_background;
    * backGround= View.GONE;
    *.....
    **/

    if (item_hase_vote[position]){
        if (item_has_like[position])
        {
            backGround= Color.GREEN;// 
        } else {
            backGround= Color.RED;
        }
    } else {
        backGround= Color.TRANSPARENT;
    }
    myViewHolder.questionTV.setText(item.getQuestion());
    myViewHolder.questionTV.setBackgroundColor(backGround);
}
@Override
public int getItemCount() {
    return arrayList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
    private TextView questionTV;
    private ImageView like, dislike;

    public MyViewHolder(final View itemView) {
        super(itemView);

        questionTV = (TextView)itemView.findViewById(R.id.question_tv);
        like = (ImageView)itemView.findViewById(R.id.like);
        dislike = (ImageView)itemView.findViewById(R.id.dislike);

        like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Item  been voted
                item_hase_vote[getAdapterPosition()] = true;
                //Item got Like save in boolean array by row position
                item_has_like[getAdapterPosition()] = true;
                //notify your adapter
                notifyDataSetChanged();
                /*OR Here comes the code where You save Item in Your Data Base.*/
            }
        });
        dislike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Item  been voted
                item_hase_vote[getAdapterPosition()] = true;
                // Item got DisLike save in boolean array by row position
                item_has_like[getAdapterPosition()] = false;
                //notify your adapter
                notifyDataSetChanged();

                /*OR Here You Remove item on Dislike
                arrayList.remove(getAdapterPosition());
                notifyItemRemoved(getAdapterPosition());
                notifyItemRangeChanged(getAdapterPosition(),arrayList.size());
                */
            }
        });
    }
}

}

还有你的Activity:

public class SomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_some);

    ArrayList<SomeModel> arrayList = new ArrayList<>();
    for (int i = 0; i <77 ; i++) {
        arrayList.add(new SomeModel("Question " + i));
    }
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_rv);
    SomeAdapter adapter = new SomeAdapter(arrayList);
    recyclerView.setAdapter(adapter);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(layoutManager);

}

}

通过 adapterPosition 将所选项目保存为布尔值、字符串、整数....[],适配器始终知道每个项目发生了什么,因此您的列表始终会被安排。

祝你好运!

我找到了过滤整个数据库的解决方案。在我的问题中,我只想在单独的 activity 中获取 liked/disliked 项目,尽管我之前的代码显示了已过滤的项目,但有间隙。 在下面的代码中,我更改了 DatabaseReferences(mDatabase - 具有完整项目列表的节点和 mDatabaseItemsLiked - 具有项目 uid 和用户 uid 的节点)。

这只给出了只有数字的空卡片作为 likedItems,但是为了从 mDatabase(完整列表)中获取名称,我使用了 dataSnapshot.getValue(Item.class).getItemName()。

firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Item, 
MainActivity.ItemViewHolder>(
        Item.class,
        R.layout.list_item,
        MainActivity.ItemViewHolder.class,
        mDatabaseItemsLiked

) {
    @Override
    protected void populateViewHolder(final MainActivity.ItemViewHolder
            viewHolder, final Item model, final int position) {

        final String itemKey = getRef(position).getKey();

        mDatabase.child(itemKey).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
viewHolder.itemNameSetup(dataSnapshot.getValue(Item.class).getItemName());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {

                            Intent itemSheetIntent = new Intent(LikedItemsActivity.this, ItemSheetActivity.class);
                            adatlapIntent.putExtra("item_key", itemKey);
                            startActivity(itemSheetIntent);
                        }
                    });

这对我来说没有任何问题。我希望它是网络高效的。

我也遇到了同样的问题。我的想法是,如果 RelativeLayout 一个接一个地加载,高度 = 0,规格将 remove.So 它适合我。

这是我的 ViewHolder。我在这里介绍一下我的相关布局。

   public static class BlogViewHolder extends RecyclerView.ViewHolder {
            View mView;
            TextView txtdate;
            RelativeLayout con_rel;
            String name_day = "no name";

            public BlogViewHolder(View itemView) {
                super(itemView);
                mView=itemView;
                con_rel=(RelativeLayout)itemView.findViewById(R.id.con_rel);
                txtdate = (TextView)itemView.findViewById(R.id.day);
            }
    } 

我设置的是高度宽度

    con_ref=FirebaseDatabase.getInstance().getReference().child("/consultation");
FirebaseRecyclerAdapter<Consultation,SelectConsaltation.BlogViewHolder>recyclerAdapter=new FirebaseRecyclerAdapter< Consultation,SelectConsaltation.BlogViewHolder>(
                    Consultation.class,
                    R.layout.consultation_card,
                    SelectConsaltation.BlogViewHolder.class,
                    con_ref
            ) {
     @Override
                protected void populateViewHolder(final SelectConsaltation.BlogViewHolder viewHolder, final Consultation model, final int Consultation) {

                    Shedule_ref.child(model.getScheduleID()).child("Day").addValueEventListener(new ValueEventListener() {
                       ViewGroup.LayoutParams params = viewHolder.con_rel.getLayoutParams();
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            name_day = dataSnapshot.getValue(String.class);

                            if (doctor_id_from_doctor.equals( model.getDoctorID() )){

                                SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
                                Date strDate = null;

                                try {
                                    strDate = sdf.parse(model.getDate());
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                                if(System.currentTimeMillis()<=strDate.getTime() ) {
                                    params.height = 300;
                                    params.width =800;
                                    viewHolder.con_rel.setLayoutParams(params);
                                    viewHolder.setDate(model.getDate(),name_day);
                                }
                                else {

                                    **params.height = 0;
                                    params.width = 0;
                                    viewHolder.con_rel.setLayoutParams(params);**
                                }

                               }
                            else {
                                params.height = 0;
                                params.width = 0;
                                viewHolder.con_rel.setLayoutParams(params);
                            }
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });


                }
            };
            recyclerView.setAdapter(recyclerAdapter);


        }

我的名片查看码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/con_rel"
    android:layout_marginRight="10dp"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="2dp"
    android:layout_marginBottom="3dp"
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content" android:background="#a2ffffff">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_marginTop="3dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/day"
            android:layout_marginTop="10dp"
            android:textSize="18sp"
            android:layout_marginLeft="5dp"
            android:textColor="@color/colorBlack"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/_07th_of_sunday_january_2018_at_9_00am"/>
        <TextView
            android:id="@+id/nextnumber"
            android:layout_marginLeft="5dp"
            android:textSize="18sp"
            android:textColor="@color/colornextnumber"
            android:textStyle="bold"
            android:layout_marginTop="20dp"
            android:text="@string/next_avealable_number_is_04"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/booknow"
            android:textStyle="bold"
            android:textSize="18sp"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="240dp"
            android:layout_marginBottom="10dp"
            android:textColor="@color/colorbookNow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/book_now"/>
    </LinearLayout>
</RelativeLayout>

这是我的inreface

使用此代码删除占用的 space :

ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = 0;
holder.itemView.setLayoutParams(params);