android recyclerview setVisibility View.GONE仍然占用空间

时间:2017-09-18 10:04:46

标签: android android-recyclerview visibility cardview

我想仅列出我的recyclerview中不喜欢的项目。我在MainActivity的rv中有完整的项目列表(这里没有设置可见性)。我可以通过点击图像按钮为每个项目设置喜欢或不喜欢。 MainActivity显示完整的项目列表(cardviews),显示imagebutton喜欢与否。如果喜欢该项,则将其作为单独条目存储在firebase数据库中,使用项目键(firebase key .push)而不是项目下。 (在firebase db中我有用户,项目,喜欢)。

这是我的子活动代码DislikedItemsActivity,我想只显示对于喜欢的项目使用setVisibility(View.GONE)不喜欢的项目。这仍然保留了View.GONE项目的项目之间的空间(尽管这些卡片视图是空的)。

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,将margin设置为0,将xml中的布局大小设置为wrap_content。我能得到的最好的是使用mRecyclerView.getAdapter()。notifyItemRemoved(position);来获得没有空间的不喜欢的项目,但是向后滚动列表整个rv搞砸了(重复条目,空格,无序列表)。

我不知道如何在新活动中仅列出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占据整个屏幕),当我开始滚动列表时(从1.可见项目到下一个可见项目) item)如果有空间(item1 vis和下一个vis项目是4),重新排列,我可以看到下一个可见项目(item4)移动到1.可见项目,然后列表的其余部分安排得很好,直到我开始向后滚动,然后用空格和双重输入重新排列rv。该列表来回传播直到两端(这是完整项目列表的长度而不仅仅是不喜欢的项目),但可见项目全部搞砸了。

4 个答案:

答案 0 :(得分:1)

我找到了过滤整个数据库的解决方案。在我的问题中,我想在一个单独的活动中只获得喜欢/不喜欢的项目,虽然我之前的代码显示过滤的项目,但有差距。 在下面的代码中,我更改了DatabaseReferences(mDatabase -node包含完整的项目列表,mDatabaseItemsLiked -node包含项目uid和用户uid)。

这只给出了只有number作为likesItems的空卡,但是为了从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);
                        }
                    });

这对我没有任何问题。我希望它具有网络效率。

答案 1 :(得分:0)

您可以尝试将喜欢的ítem存储在boolean array中以及稍后的populateViewHolder中,检查ítem是否喜欢o并设置可见性。

我会这样做:

  1. 在你的课堂上声明:
  2.   

    private boolean [] itemLiked;

    1. 在您的构造函数中:
    2.   

      this.itemLiked = new boolean [arrayOfAllItems.size]

      1. 点击活动:
      2.   

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

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

            

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

        2. 希望它有所帮助,祝你好运!

          <强> EDITED 我不明白你想要做什么,这就是为什么我给你留下两个案例的代码。 案例1.标记和标记行。 案例2.保存到数据库或删除。

          继续完整的代码

          活动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"/>
          

          制作模型类:

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

          制作适配器类:

          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());
                          */
                      }
                  });
              }
          }
          

          }

          和你的活动:

          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在boolean,String,int .... []中保存所选项目,适配器总是知道每个项目都在进行,并且总是会安排你的列表。

          祝你好运!

答案 2 :(得分:0)

我也遇到了同样的问题。我认为如果RelativeLayout一个接一个加载,高度= 0,那么规格将会删除。所以它对我有用。

这是我的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 enter image description here

答案 3 :(得分:0)

使用此代码删除占用的空间:

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