リストアイテムの高さが可変の、かなり複雑なListViewがあります。特定の条件下では、リストアイテムに追加のビューを表示する必要がありますが、これはデフォルトでは非表示になっています(View.GONE)。これを有効(View.VISIBLE)にすると、リストアイテムの高さが大きくなります(または、少なくとも想定されています)。
問題:アイテムのルートレイアウトをwrap_contentに宣言し、アイテムの各コンポーネントをfill_parentに宣言しても、アイテムの高さを変更することになっている非表示/表示のビューは、親の代わりに下部で切り取られます(アイテムのレイアウト)を完全に表示するために高さが大きくなります。
ListViews、アイテムのレイアウト、アイテムの高さに関連する落とし穴がありますか?
その他の観測:
テストの目的で、リストアイテムのレイアウトを減らして、ルートのLinearLayoutとImageViewのみを含めるようにしました。 LinearLayoutの高さを例えば200dipおよびImageViewをfill_parentにすると、ImageViewが親によって設定された200dipの制限に達するまでImageViewが大きくなることが予想されます。
ただし、代わりに画像はビットマップリソースと同じ高さになり(wrap_contentに設定した場合と同じように)、リストアイテム全体が同じ高さになります(つまり、wrap_contentに設定した場合と同じように)。
ただし、画像の高さをたとえば200dipの場合、リストアイテムの高さが増加し、アイテムのレイアウトも増加します。
つまり、リストアイテムレイアウトのlayout_heightは完全に無視され、ハードコードされたピクセル値以外のImageViewの高さの値も完全に無視されます。
私はこれを修正することができましたが、whyがわかりません。
前述したように、リストアイテムレイアウトのlayout_height
をwrap_content
に設定しました(ListViewの高さが無限にあることを考えると、fill_parent
はここでは意味がないため)。
ただし、すべてのビューのlayout_height
を設定していましたinsideそのレイアウトはfill_parent
に設定されていました。代わりにwrap_content
に設定すると、問題はなくなりました。
これにより、他に2つの質問が発生します。
1)親がfill_parent
である場合、wraps_content
を要求するビューのセマンティクスは何ですか?どのサイズのリクエストが優先されますか?
2)fill_parent
が機能しないように見える場合、どのようにしてリスト項目をビューで埋めますか?
ご意見をお寄せいただきありがとうございます。
これを試してください: http://www.Java2s.com/Code/Android/UI/setListViewHeightBasedOnChildren.htm
public class Utils {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
}
行をどのように膨らませていますか?
現在使用していない場合は、LayoutInflater#inflate(layoutId, parent, false)
を使用してみてください(parent
はgetView()
またはnewView()
に提供されるAdapterView
です):
v = getLayoutInflater().inflate(R.layout.list_item, parent, false);
ScrollViewがラッパーになることにより、レイアウトの問題が発生する可能性があります
私は http://developer.Android.com/reference/Android/widget/ExpandableListView.html でいくつかの注意を見つけました
"...注:親のサイズも厳密に指定されていない場合、XMLでExpandableListViewのAndroid:layout_height属性に値wrap_contentを使用することはできません(たとえば、親がScrollViewの場合、wrap_contentも指定できないため、ただし、ExpandableListViewの親のサイズが100ピクセルなどの特定のサイズである場合は、wrap_contentを使用できます。
ScrollViewの折り返しを削除すると、線形レイアウトが正常に機能し始めました。これで、ScrollViewにデータをラップする方法を理解できるようになりました。神よ私を救い給え
とにかく、これは本当に奇妙な動作です。 fill_parentは本当に正しい表現ではないと思います。 heirarchyviewerツールを使用すると、layout_widthとleayout_heightのWRAP_CONTENTとMATCH_PARENTの値が常に表示されます。したがって、おそらくfill_parentは実際にはmatch_parentを意味し、これによって私は認知的不協和に陥ります。
「AbsListView.LayoutParams」を使用して、「Adapter.getView()」内で幅と高さを手動で構成します。
サイズ変更するリスト項目としてカスタムView
を使用している場合、PeBekの答えから取得して、View
を構築するときにこれを行うことができます。
addOnLayoutChangeListener(
new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View _, int __, int ___, int ____, int bottom, int _____, int ______,
int _______, int old_bottom) {
final ListView list_view = (ListView) getParent();
final ViewGroup.LayoutParams params = list_view.getLayoutParams();
params.height += bottom - old_bottom;
list_view.setLayoutParams(params);
list_view.requestLayout();
}
});
View
のサイズが変更されると、このコールバックメソッドが実行され、ListView
の高さが更新されて、高さの変化が反映されます(デルタボトム)。他の値は、view
(ビューへの参照)、left
、top
、right
、bottom
、old_left
、old_top
、old_right
、old_bottom
。ビューを展開したり折りたたんだりするために機能します。
API 11はOnLayoutChangeListener
に必要です。下位互換性のある方法があるかどうかはわかりません。
これは私のために働く
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:padding="@dimen/activity_vertical_margin">
<TextView
Android:id="@+id/tv_status"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:textSize="17sp"
Android:text="@string/text_list_devices" />
<ListView
Android:id="@+id/lv_paired"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="@dimen/activity_vertical_margin"
Android:cacheColorHint="#00000000"
Android:layout_above="@+id/signup_t"
Android:layout_below="@id/tv_status"
/>
<Button
Android:id="@+id/signup_t"
style="?android:textAppearanceSmall"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="20dp"
Android:textColor="@Android:color/white"
Android:layout_alignParentBottom="true"
Android:text="Print All Records"
Android:typeface="sans"
Android:layout_marginLeft="45dp"
Android:layout_marginRight="45dp"
Android:textSize="24sp"
Android:background="@drawable/selector_for_button"
Android:textStyle="bold" />
</RelativeLayout>
私は同じ問題を抱えていました:デバイスが水平方向よりも垂直方向にあるときでも、すべての画面を満たすアクティビティ内のリストを持ちたいです。 fill_parentを必要とする高さを持つ線形レイアウトを使用して問題を解決し、layout_weightが1に設定されている間にリスト内のアイテムの高さを0dpに設定します。
Android:layout_weight="1"
Android:layout_height="0dp"