2010-04-14 38 views
20

Làm cách nào để ẩn một mục trong một ListView hoặc ít nhất đặt chiều cao của nó thành 0?Android: Cách ẩn một Mục ListView

Tôi đã thử đặt chế độ hiển thị của Chế độ xem thành GONE nhưng vẫn duy trì không gian của mục (chiều cao).

+1

Bạn có chắc chắn về xét của bạn về View.GONE? – Samuh

+0

Xem http://stackoverflow.com/questions/5041499/how-to-hide-an-item-in-a-listview-in-android – mattlary

Trả lời

2

Tôi đã làm một số tinkering với danh sách kéo và thả từ here. Khi một mục được bật ra khỏi danh sách được di chuyển xung quanh không gian ô mà nó chiếm giữ có chiều cao là 1px (xem dòng 238) để nó xuất hiện "biến mất". Tôi không thể tìm thấy một cách để xử lý này tốt hơn như thiết lập chiều cao đến 0 không như khả năng hiển thị GONE.

Điều đó nói rằng, Nếu bạn thực sự muốn loại bỏ một hàng ít tạm thời hơn, bạn nên thay đổi sự ủng hộ của số Adapter và gọi notifyDataSetChanged() trên đó.

0

thêm vào đối tượng ListView của bạn: android: dividerHeight = "0px" android: chia = "# FFFFFF"

phân màu không quan trọng chỉ thiết dividerHeight không hoạt động

này xóa dải phân cách mặc dù ...

2

Tôi đã xem mã nguồn. Và chỉ có một cách để ẩn mục mà không cần notifyDataSetChanged(). Bạn phải đặt chế độ hiển thị GONE cho tất cả chế độ xem bên trong và xóa hình nền và phần đệm cho chế độ xem của mục.

Lưu ý: Hàng có phần tử vô hình như vậy sẽ được chọn.

P.S: Điều này rất hữu ích đối với ExpandableListView nếu bạn muốn ẩn nhóm tự xem.

24

Ressurecting một câu hỏi cũ, nhưng tôi chỉ có vấn đề này, nơi tôi muốn ẩn các mục danh sách tạm thời dựa trên các tiêu chí bên ngoài của dữ liệu danh sách. Những gì tôi đã kết thúc làm là tạo ra một "null item" bố trí trong xml và trả lại dựa trên tiêu chí của tôi thay vì xem chuyển đổi trong getView() ...

thay vì trả về convertView, tôi trả về null_item của tôi .. .

return inflater.inflate(R.layout.null_item, null); 

null_item.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 

</LinearLayout> 
+7

Tại sao không chỉ trả về một đối tượng Chế độ xem mới? Bằng cách này, bạn sẽ không thêm chi phí của chế độ xem lạm phát. – mdelolmo

+0

@tawani không giải pháp được đề xuất này có phù hợp với bạn không? Vui lòng đánh dấu mục này là câu trả lời. Phương pháp – Sufian

+4

@ mdelolmo hoạt động. Tôi chỉ thử nghiệm nó và nó giúp bạn tiết kiệm được sự cần thiết cho các tập tin xml thêm và lạm phát. Bạn thậm chí không cần thiết lập các tham số layout, chỉ cần 'return new View (context);' –

7

Khi nói đến ListView, để làm cho nó hiệu quả, chúng tôi sử dụng ViewHolder mẫu. Cách sử dụng ViewHolder Pattern và R.layout.row_null của xml sau

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 
</LinearLayout> 

là để sử dụng với getViewTypeCount()getItemViewType(int position) như sau.

@Override 
    public int getViewTypeCount() { 
     return 2; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return (hideStatusCheck(position)) ? 1 : 0; 
    } 

    @Override 
    public View getView(int pos, View convertView, ViewGroup parent) { 
     View rowView = convertView; 

     if (hideStatusCheck(pos)) { 
      if (rowView == null || rowView.getTag() != null) { 
       LayoutInflater inflater = mActivity.getLayoutInflater(); 
       rowView = inflater.inflate(R.layout.row_null, parent, false); 
      } 
     } else { 
      if (rowView == null) { 
       rowView = inflateNormalView(parent); 
      } else if (rowView.getTag() == null) { 
       rowView = inflateNormalView(parent); 
      } else { 
       ViewHolder holderToCheck = (ViewHolder) rowView.getTag(); 
       Integer storedPos = (Integer) holderToCheck.getTag(POSITION); 
       if (storedPos == null || storedPos != pos) 
        rowView = inflateNormalView(parent); 
      } 
      ViewHolder holder = (ViewHolder) rowView.getTag(); 
      holder.setTag(POSITION,pos); 
         /* 
         Populate data 
         */ 
      return rowView; 
    } 

    private View inflateNormalView(ViewGroup parent) { 
        View rowView; 
     LayoutInflater inflater = mActivity.getLayoutInflater(); 
     rowView = inflater.inflate(R.layout.normal_item, parent, false); 
     ViewHolder viewHolder = new ViewHolder(); 
     assert rowView != null; 
        /* Initiate normal findViewById thing*/ 
     rowView.setTag(viewHolder); 
     return rowView; 
    } 

Chúng tôi làm việc kiểm tra xem loại của mục đó và nếu nó đáp ứng việc kiểm tra ẩn, nó sẽ trở lại 1, nếu không 0. Các ListView biết rằng sẽ có 2 loại Xem từ getViewTypeCount. Bây giờ, getView sẽ trả về Viewrorror View tùy thuộc vào hideStatusCheck. Để tạo một ListView mạnh mẽ, chúng tôi muốn sử dụng mẫu ViewHolder. Chúng ta không cần sử dụng ViewHolder khi nó bị ẩn. Chúng ta đơn giản thổi phồng R.layout.row_null và trả về nó. Chúng ta sẽ sử dụng ViewHolder cho R.layout.normal_item. Đây là phần khó khăn giả định việc kiểm tra ẩn không phải là tĩnh. Séc đầu tiên của rowView==null là tiêu chuẩn.Kiểm tra thứ hai của rowView.getTag()==null là để xem liệu Chế độ xem có quay trở lại bình thường không. Kiểm tra thứ ba trong mệnh đề else cuối cùng là kiểm tra xem ViewHolder được giữ lại trong thẻ có phải là ViewHolder hay không. Nếu các điều kiện này được đáp ứng, chúng tôi sẽ luôn làm tăng lượt xem. Có, đúng là, mẫu ViewHolder không được sử dụng trong suốt nhưng nó sử dụng để mở rộng nhất định. Nó tốt hơn là không có gì.

0

Tôi nghĩ rằng tôi có một giải pháp dễ dàng hơn/an toàn hơn nhiều: bạn chỉ cần "nhúng" mục của mình trong Bố cục và thay đổi chế độ hiển thị của bố cục gốc này.

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

    <!-- Embed ListView Item into a "parent" Layout --> 
    <LinearLayout 
     android:id="@+id/parentLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- This is the normal content of your ListView Item --> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Hello" /> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="World" /> 

    </LinearLayout> 
</LinearLayout> 

Sau đó, trong mã của bạn chỉ làm:

public View getView(int position, View view, ViewGroup parent) { 
    if (view == null) { 
     LayoutInflater li = mActivity.getLayoutInflater(); 
     view = li.inflate(R.layout.my_listview_item, null); 
    } 
    LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout); 
    if (shouldDisplayItem(position)) { 
     parentLayout.setVisibility(View.VISIBLE); 
    } else { 
     parentLayout.setVisibility(View.GONE); 
    } 
    return view; 
} 

Bằng cách này bạn luôn luôn sử dụng/tái sử dụng cùng một mục, và chỉ cần ẩn/hiển thị nó.

+0

Đây là câu trả lời đúng, tôi sẽ viết nó :) –

11

nếu bạn muốn ẩn các mục như thế này:

convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1)); 
convertView.setVisibility(View.GONE); 

không thể AbsListView.LayoutParams (-1,0);

nếu convertview được tái sử dụng bạn nên thêm dưới đây để thiết lập nó chiều cao trở lại:

if(convertView.getVisibility() == View.GONE) { 
    convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT)); 
    convertView.setVisibility(View.VISIBLE); 
} 
Các vấn đề liên quan