How to hide an item in a listview in Android

后端 未结 11 1049
天涯浪人
天涯浪人 2020-12-03 07:15

I know, this question was asked before, but I haven\'t seen a working answer for it.

Is there any way to hide some items in a ListView without changing

相关标签:
11条回答
  • 2020-12-03 07:48

    Here my solution:

    public class MyAdapter extends ArrayAdapter<MyEntry> {
    
        public MyAdapter(Context context, int resId) {
            super(context, resId);
        }
    
        private List<MyEntry> visibleEntries() {
    
            List<MyEntry> result = new ArrayList<MyEntry>();
    
            int i = 0;
            try {
                while (true) {
                    if (getItem(i).isVisible())
                        result.add(getItem(i));
                    i++;
                }
    
            } catch(Exception e) {
    
            }
    
            return result;
    
        }
    
        @Override
        public int getCount() {
            return visibleEntries().size();
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            LinearLayout layout = 
                convertView == null ? 
                    (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.entry, parent, false) :
                    (LinearLayout) convertView;
    
            MyEntry entry = visibleEntries().get(position);
    
            ...
    
            return layout;
        }
    }
    
    0 讨论(0)
  • 2020-12-03 07:56

    I tried several solutions including setVisibitlity(View.GONE) and inflating a default null view but all of them have a common problem and that's the dividers between hidden items are stacked up and make a bad visible gray space in large lists.

    If your ListView is backed by a CursorAdapter then the best solution is to wrap it with a CursorWrapper.

    So my solution (based on @RomanUsachev answer here) is this:

    FilterCursorWrapper

       public class FilterCursorWrapper extends CursorWrapper {
        private int[] index;
        private int count = 0;
        private int pos = 0;
    
        public boolean isHidden(String path) {
    
          // the logic to check where this item should be hidden
    
          //   if (some condintion)
          //      return false;
          //    else {
          //       return true; 
          //   }
    
           return false;
    
        }
    
        public FilterCursorWrapper(Cursor cursor, boolean doFilter, int column) {
            super(cursor);
            if (doFilter) {
                this.count = super.getCount();
                this.index = new int[this.count];
                for (int i = 0; i < this.count; i++) {
                    super.moveToPosition(i);
                    if (!isHidden(this.getString(column)))
                        this.index[this.pos++] = i;
                }
                this.count = this.pos;
                this.pos = 0;
                super.moveToFirst();
            } else {
                this.count = super.getCount();
                this.index = new int[this.count];
                for (int i = 0; i < this.count; i++) {
                    this.index[i] = i;
                }
            }
        }
    
        @Override
        public boolean move(int offset) {
            return this.moveToPosition(this.pos + offset);
        }
    
        @Override
        public boolean moveToNext() {
            return this.moveToPosition(this.pos + 1);
        }
    
        @Override
        public boolean moveToPrevious() {
            return this.moveToPosition(this.pos - 1);
        }
    
        @Override
        public boolean moveToFirst() {
            return this.moveToPosition(0);
        }
    
        @Override
        public boolean moveToLast() {
            return this.moveToPosition(this.count - 1);
        }
    
        @Override
        public boolean moveToPosition(int position) {
            if (position >= this.count || position < 0)
                return false;
            return super.moveToPosition(this.index[position]);
        }
    
        @Override
        public int getCount() {
            return this.count;
        }
    
        @Override
        public int getPosition() {
            return this.pos;
        }
    }
    

    when your Cursor is ready, feed to FilterCursorWrapper with your desired column index

    FilterCursorWrapper filterCursorWrapper = new FilterCursorWrapper(cursor, true,DATA_COLUMN_INDEX);
    
    dataAdapter.changeCursor(filterCursorWrapper);
    

    and if you do filtering and sorting, don't forget to use FilterCursorWrapper everywhere:

        dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence constraint) {
                String selection = MediaStore.Video.Media.DATA + " LIKE '%" + constraint.toString().toLowerCase() + "%'";
                return new FilterCursorWrapper(context.getContentResolver().query(videoMediaUri, columns, selection, null, null), true, DATA_COLUMN_INDEX);
            }
        });
    

    and for refreshing the list, that's sufficient to query with empty filter:

    dataAdapter.getFilter().filter("");
    

    and you're done, simply by changing the logic of isHidden method, you control to show or hide hidden items. And the benefit is that you don't see undesired dividers stacked up. :-)

    0 讨论(0)
  • 2020-12-03 07:57

    You can either write your own ListAdapter or subclass one of the existing ones.

    In your ListAdapter, you would simply filter out the items you do not want displayed by returning modified values for getCount(), getItem() and getItemId() as appropriate.

    0 讨论(0)
  • 2020-12-03 07:59

    listview_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp" >
    
    <ImageView
        android:id="@+id/imgView"
        android:layout_width="40dp"
        android:layout_height="20dp"/>
    
    <TextView
        android:id="@+id/totalTime"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:textSize="14dp"
        android:text="16 分鐘"
        android:layout_weight="1"
        android:paddingLeft="10dp" />
    <TextView
        android:id="@+id/currentTime"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:textSize="14dp"
        android:text="11:46"
        android:layout_weight="1"
        android:gravity="right"
        android:paddingLeft="10dp" />
    <ImageView
        android:id="@+id/img"
        android:layout_width="40dp"
        android:layout_height="20dp"
        />
    </LinearLayout>
    

    MainActivity.java

    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                view.findViewById(R.id.img).setVisibility(View.GONE);
    
            }
        });
    

    it's effective for me.

    0 讨论(0)
  • 2020-12-03 08:02

    Simple way to resolve this problem for me, just parse and check your list in activity before calling method "setAdapter", for example:

    for(Object a : list){
    //here must be some condition for getting all items without hidden
    newList += a;
    }
    setAdapter(newList);
    
    0 讨论(0)
提交回复
热议问题