ListViewでアイテムを非表示にしたり、少なくともその高さをゼロに設定したりするにはどうすればよいですか?
ビューの可視性をGONEに設定しようとしましたが、それでもアイテムのスペース(高さ)は維持されます。
古い質問を復活させましたが、リストデータ以外の基準に基づいてリストアイテムを一時的に非表示にしたいというこの問題が発生しました。私がやったことは、xmlで「nullアイテム」レイアウトを作成し、getView()の変換ビューではなく、私の基準に基づいてそれを返すことでした。
convertViewを返す代わりに、null_itemを返しました...
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>
このようにアイテムを非表示にする場合:
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
convertView.setVisibility(View.GONE);
absListView.LayoutParams(-1,0);にすることはできません。
convertviewを再利用する場合は、以下にこれを追加して高さを元に戻す必要があります。
if(convertView.getVisibility() == View.GONE) {
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
convertView.setVisibility(View.VISIBLE);
}
ListViewに関しては、効率を上げるために、ViewHolderパターンを使用します。次のxmlのViewHolderパターンとR.layout.row_nullを使用する方法
_<?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>
_
getViewTypeCount() および getItemViewType(int position) で次のように使用します。
_ @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;
}
_
アイテムのビュータイプのチェックを行い、非表示チェックに一致する場合は1を返し、それ以外の場合は0を返します。ListViewは、getViewTypeCountから2つのタイプのビューがあることを認識しています。これで、getViewは、hideStatusCheckに応じて適切なビューを返します。堅牢なListViewを作成するには、ViewHolderパターンを使用します。非表示の場合、ViewHolderを使用する必要はありません。 R.layout.row_nullを膨らませて返すだけです。 R.layout.normal_itemにはViewHolderを使用します。非表示チェックが静的ではないと仮定した場合の注意が必要な部分は次のとおりです。 _rowView==null
_の最初のチェックは標準です。 rowView.getTag()==null
の2番目のチェックは、ビューが非表示から通常に戻っているかどうかを確認することです。最後のelse
句の3番目のチェックは、タグに保持されているViewHolderが正しいViewHolderであるかどうかをチェックすることです。これらの条件が満たされると、常にビューが再び膨らみます。はい、確かに、ViewHolderパターンは全体で使用されているわけではありませんが、特定の範囲で使用されています。何もないよりはましです。
ソースコードを見てきました。そして、notifyDataSetChanged()
なしでアイテムを非表示にする唯一の方法があります。すべての内部ビューに可視性GONE
を設定し、アイテムのビューの背景画像とパディングを削除する必要があります。
注:このような非表示の要素を持つ行は選択可能です。
追伸:これは、グループビューを自分で非表示にする場合にExpandableListView
に非常に役立ちます。
ここ からドラッグアンドドロップリストをいじくり回しました。アイテムがリストからポップされて、占有されているセルスペース内を移動すると、その高さは1pxに設定されるため(238行目を参照)、「なくなった」ように見えます。高さを0に設定すると、可視性が失われるため、これをより適切に処理する方法を見つけることができませんでした。
とは言うものの、本当に一時的に行を削除したい場合は、Adapter
のバッキングを変更して、その上でnotifyDataSetChanged()
を呼び出すことをお勧めします。
listViewオブジェクトに追加します:Android:dividerHeight = "0px" Android:divider = "#FFFFFF"
仕切りの色は、dividerHeightを設定するだけでは問題ありません。
しかし、これは仕切りを削除します...
私にははるかに簡単で安全な解決策があると思います。アイテムをレイアウトに「埋め込み」、この親レイアウトの表示を変更するだけです。
<?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>
次に、コードで次のようにします。
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;
}
このようにして、常に同じアイテムを使用/再利用し、それを非表示/表示するだけです。