21

ScrollView 内に ListView を埋め込むときに問題が発生しました。または、少なくともそれが問題の原因だと思います。ListView 要素はかなり単純なものです。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/general_background_list_middle" 
    android:paddingTop="4dp"
    android:paddingBottom="4dp"
    android:paddingRight="0dp"
    android:paddingLeft="0dp">

    <ImageView
        android:id="@+id/chat_friends_avatar"       
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_marginLeft="7dp"
        android:layout_marginRight="8dp"
        android:paddingRight="0dp" 
        android:paddingLeft="0dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/friends_icon_avatar_default"/>

    <TextView
        android:id="@+id/chat_message_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/chat_friends_avatar"
        android:layout_alignParentTop="true"
        android:layout_marginRight="35dp"
        android:maxLines="10"
        android:textSize="12dp"/>

    <TextView
        android:id="@+id/chat_friend_name"
        android:layout_width="140dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="3dp"
        style="@style/SubText"
        android:layout_toRightOf="@id/chat_friends_avatar"      
        android:layout_below="@id/chat_message_text" />

    <TextView
        android:id="@+id/chat_message_time"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="8dp"
        android:layout_marginTop="3dp"
        style="@style/SubText"
        android:layout_alignParentRight="true"
        android:layout_below="@id/chat_message_text" />

</RelativeLayout>   

ただし、そのような要素のリストを ScrollView に埋め込むと、他の要素の間に行が完全に表示されず、テキストが折り返されている場合に行が切り取られます (下の画像を参照)。ListView は、ScrollView で次のようにインスタンス化されます。

<ListView
android:id="@+id/info_chat_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:cacheColorHint="@color/frame_background_color"
android:clickable="false"
android:divider="@null"
android:footerDividersEnabled="false"
android:focusable="false" >
</ListView> 

ListView の高さが「wrap_content」に設定されている場合、最初の要素のみが表示されます。そのため、リストの行の高さを計算するメソッドを使用しています。

private int getCommentsListHeight() {
        if (mChatAdapter != null && mChatAdapter.getCount() != 0) {
            if (mChatList != null) {// && mCommentsListItemHeight == 0) {
                mCommentsListItemHeight = 0;
                for (int i = 0; i < mChatAdapter.getCount(); i++) {
                    // Get view item height
                    View viewItem = mChatAdapter
                            .getView(i, new View(OnAirActivity.this), mChatList);
                    viewItem.measure(0, 0);
                    Logger.d(LOGTAG, "View " + i + " measured height = " + viewItem.getMeasuredHeight());
                    mCommentsListItemHeight += viewItem.getMeasuredHeight();
                }
            }
            //return mChatAdapter.getCount() * mCommentsListItemHeight;
            return mCommentsListItemHeight;
        } else {
            return 0;
        }
    }

残念ながら、TextView 内のテキストが複数の行にわたって折り返されている場合でも、getMeasuredHeight() メソッドによって返される行要素の高さは一定です。また、行要素内の TextView で呼び出される getLineCount() は、テキストが折り返されていても 1 を返します。

一方、この ListView が LinearLayout に埋め込まれている場合、すべてが正常に機能し、完全なリストがクリッピングなしで表示されます。

ここで何が間違っている可能性があるかについて何か提案はありますか? リスト要素の高さを手動で測定するという考えは本当に好きではありませんが、明らかにうまくいきませんが、なぜアンドロイドは ScrollView 内の ListView をうまく引き伸ばしてすべてをそこに収めることができないのですか?

クリップされたリスト: 画像を見る

4

10 に答える 10

40

https://stackoverflow.com/users/205192/dougwによって作成されたこのメソッドを使用します

 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);
    }
于 2013-04-19T11:55:16.047 に答える
11

ListView 自体にスクロール機能が含まれているため、 内にカプセル化するのは悪い習慣です。そのようなビューの階層を含まないソリューションを実装する必要があり、それが魔法をかけてくれることを願っています:)ListViewScrollView

于 2012-05-22T20:12:56.577 に答える
2

プロジェクトでも同じ問題が発生しました。ScrollView内に単純なLinearLayoutを作成する必要があります。その後、LayoutInflaterを使用してlistviewitemxmlで新しいビューを作成する必要あります。作成後、すべてのデータを新しいビューに配置し、子ビューとしてLinearLayoutに追加します

linearLayot.addView(newView, position_you_need).

それがあなたを助けることを願っています!

于 2012-05-23T06:43:58.357 に答える
2

ScrollViewを使用したメインレイアウトのリソース:

<ScrollView android:layout_height="fill_parent" android:layout_width="fill_parent">
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/parentLayout"/>
</ScrollView>

アイテムを挿入するコードは次のとおりです。

parentLayout.removeAllViews();
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = comments.size() - 1; i >= 0; i--) {
CommentInfo comment = comments.get(i);
View view = inflater.inflate(your_resource_id, null, false);

TextView commentsContent =(TextView)view.findViewById(R.id.commentContent);
if (commentsContent != null) {
    String data = String.format("%s (by %s, %s)",  comment.getCommentText(), comment.getUserName(),
        commentsContent.setTextSize(st.getTextSize());
    commentsContent.setText(data);

}

parentLayout.addView(view, 0);

}       
于 2012-05-24T04:26:55.747 に答える
1

私は、ScrollView 内で ListView 要素を使用しないという推奨事項を心に留め、必要なことを達成するために少し強引な方法を使用することにしました。表示する必要がある最大 5 つのリスト行の定数があるため、xml ファイルから ListView のインスタンス化を削除し、行の 5 つのインスタンスに置き換えました。

<include android:id="@+id/info_comment_1" layout="@layout/chat_single_message" />
<include android:id="@+id/info_comment_2" layout="@layout/chat_single_message" />
<include android:id="@+id/info_comment_3" layout="@layout/chat_single_message" />
<include android:id="@+id/info_comment_4" layout="@layout/chat_single_message" />
<include android:id="@+id/info_comment_5" layout="@layout/chat_single_message" />

Activity クラスでは、これらのビューの 5 つのプレースホルダーを宣言します。

private RelativeLayout mChatMessages[] = new RelativeLayout[COMMENTS_NUMBER];

それらを次のように初期化します。

mChatMessages[0] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_1);
mChatMessages[1] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_2);
mChatMessages[2] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_3);
mChatMessages[3] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_4);
mChatMessages[4] = (RelativeLayout) mMoreInfoLayout.findViewById(R.id.info_comment_5);

次に、新しいメッセージが受信されるたびに、ChatAdapter (以前に ListView に使用したものと同じもの) を使用し、その getView() メソッドを呼び出します。

protected void updateChatMessages() {
  int msgCount = mChatAdapter.getCount();
  for (int i = 0; i < COMMENTS_NUMBER; i++) {
    if (msgCount <= i) {
      mChatMessages[i].setVisibility(View.GONE);
    } else {
      mChatMessages[i] = (RelativeLayout) mChatAdapter.getView(i, mChatMessages[i], null); 
      mChatMessages[i].setVisibility(View.VISIBLE);
    }   
  }
}

変更されるのはレイアウトではなく各行のコンテンツだけであるため、pariculat ビューを再び膨らませることはありません。これは、ここでパフォーマンスが低下しないことを意味します。

これは基本的に、要素の最大数が制限された ListView の手動実装です。ただし今回は、ScrollView はそれらにうまく適合し、何もクリップされません。

動的な行数の場合、Layko によって提案されたアプローチを使用して、ビューをプログラムでインスタンス化し、ScrollView 内の LinearLayout に追加することができます。

于 2012-05-23T10:59:51.793 に答える
0

同様の問題がありました。私は

RelativeLayout
  listView
  includeLayout  

ここで、これを使用してlistViewの下にいくつかの下部ナビゲーションを含めます

<include
    android:id="@+id/includeLayout"
    layout="@layout/bottom_nav_bar"

私のlistViewは切り取られました-ヘッダーと下部のナビゲーションの間で利用可能な高さ全体を使用していません。このスレッドや他のスレッドで提案されているさまざまなxml設定を試しましたが、うまくいったのは追加することでした

android:layout_alignBottom="@+id/includeLayout"

私のリストビューに。これにより、listView が下部ナビゲーションの上部に引き下げられたように見えたため、listView は利用可能な高さをすべて使用しています (必要に応じてスクロールします)。

于 2017-05-10T13:05:55.247 に答える
0

これは私のために働く

<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>
于 2017-11-16T03:59:24.097 に答える