質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

1299閲覧

[Xamarin.Android]ListViewの高さを、アイテム数に応じて自動調節したい

PeerGynt

総合スコア8

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2023/03/23 14:07

度々お世話になります。Androidアプリ開発の初心者です。
Microsoft Learn等のサイトを参考に、見様見真似で販売管理ツールを組んでいます。

■やりたいこと

ListViewにアイテムを追加する毎に、ListViewの高さを伸ばしていきたい(アイテム数に応じて自動調節したい)

■問題点

前提として、画面レイアウトの縦が1画面内に収まらないため、全体をScroll Viewの上に乗せる形で設定しています。
その中段付近にListViewを配置しています。
ListViewのアイテムは、動的に追加しどんどん増えます。

この時、ListViewの高さを、アイテム数に応じて伸ばしていきたい(つまりスクロールさせず全行表示させたい)のですが、やり方がさっぱり判りません。

■試してみたこと

画面デザインのプロパティ設定などを、考えられる限り色々と変更してみたのですが、ダメでした。
ListViewにアイテム追加するタイミングで高さを変更できないか、と参考情報を探してみたのですが、結局よくわかりませんでした。
過去記事にも「setLayoutParams」を使用する、という記述を見つけましたが、Xamarinの記述方法がさっぱり判らず、頭を抱え込んでいます。

■開発環境等

Xamarin.Androidプロジェクト
最小Android 9.0(API28) ~ ターゲットAndroid 11.0(API30)
Win11 Pro + Visual Studio 2019(開発環境)
Android9タブレット端末 / Android11スマート端末(デバッグ用端末)

■教えて頂きたいこと

画面デザイン時のプロパティ設定であっさり解決するのでしょうか(出来そうな気がするのですが、上手くいきませんでした)
もし可能であれば、適切な設定を教えて下さい。

もしくはソース中で動的に変更すべきであれば、やり方をご教示頂きたいと思います。

Xamarin Android(C#)のやり方が一番望ましいのですが、なければJava等の記述でも結構です。
解決の糸口となりそうな情報、なんでも結構ですので、頂戴出来れば幸いです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2023/03/23 14:32 編集

ListView は画面に入りきらない部分をスクロールさせることによって多量のデータを表示するためのものです。 幾ら画面全体が ScrollView の管理下だからといって、 ListView をスクロールさせずデータがあるだけ大きくするというのは ListView の提供したい機能では無いでしょう。 スクロールさせないのであれば、コードでパネルに次々と行のレイアウトを追加するようなことを自分でするしかないように思いますが、データ量によってはビューが大量に存在することになり、資源を食うものになりそうです。(それを防ぐために使い回しの処置が ListView に入っているわけで。) あるいは、全体を ListView とし、現在 ListView の上下(?)にあるフィールド類を ListView のヘッダ・フッタ行として扱うことで、同様の状態になるのではないでしょうか。
PeerGynt

2023/03/24 00:41

>jimbeさん いつもお世話になっております。 やはりそういうことなんでしょうか……。 ScrollView上にListViewを乗せると、ListView側のスクロールバーが効かないんですよね。画面全体がスクロールしてしまって、肝心のListView側はスクロールせず。 そもそもそういう使い方は非推奨だそうで。 >あるいは、全体を ListView とし(略) そういう回避策しかないのでしょうかねえ……。 納期直前ですし、Android開発初心者の私にはちと難しそうですorz どうもありがとうございます。
guest

回答1

0

ベストアンサー

全体を ListView とし最初と最後の行をヘッダ・フッタ的として扱うので良ければ、 ListView へのアダプタを 3種類のレイアウトを扱うように getViewTypeCount/getItemViewType 等を override して出来ます。

MainActivity.java

java

1import androidx.appcompat.app.AppCompatActivity; 2 3import android.os.Bundle; 4import android.view.*; 5import android.widget.*; 6 7import java.util.*; 8 9public class MainActivity extends AppCompatActivity { 10 @Override 11 protected void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.activity_main); 14 15 ListView listView = findViewById(R.id.listView); 16 Adapter adapter = new Adapter(); 17 listView.setAdapter(adapter); 18 19 adapter.setHeader("あいうえお", "ABCDE"); 20 for(int i=1; i<=20; i++) adapter.addRow("かきくけこ"+i, "さしすせそ"+i, 100+i); 21 adapter.setFooter("ワオン", 9999); 22 } 23 24 private static class Adapter extends BaseAdapter { 25 private static final int HEADER_TYPE = 0; 26 private static final int ROW_TYPE = 1; 27 private static final int FOOTER_TYPE = 2; 28 29 private static class Header { 30 String text1, text2; 31 } 32 private static class Row { 33 String text1, text2; 34 int value; 35 } 36 private static class Footer { 37 String text; 38 int value; 39 } 40 41 private static class HeaderViewHolder { 42 final TextView text1, text2; 43 HeaderViewHolder(View itemView) { 44 text1 = itemView.findViewById(R.id.text1); 45 text2 = itemView.findViewById(R.id.text2); 46 } 47 } 48 private static class RowViewHolder { 49 final TextView text1, text2, value; 50 RowViewHolder(View itemView) { 51 text1 = itemView.findViewById(R.id.text1); 52 text2 = itemView.findViewById(R.id.text2); 53 value = itemView.findViewById(R.id.value); 54 } 55 } 56 private static class FooterViewHolder { 57 final TextView text, value; 58 FooterViewHolder(View itemView) { 59 text = itemView.findViewById(R.id.text); 60 value = itemView.findViewById(R.id.value); 61 } 62 } 63 64 private Header header = new Header(); 65 private List<Row> rowList = new ArrayList<>(); 66 private Footer footer = new Footer(); 67 68 void setHeader(String text1, String text2) { 69 header.text1 = text1; 70 header.text2 = text2; 71 notifyDataSetChanged(); 72 } 73 void addRow(String text1, String text2, int value) { 74 Row row = new Row(); 75 row.text1 = text1; 76 row.text2 = text2; 77 row.value = value; 78 rowList.add(row); 79 notifyDataSetChanged(); 80 } 81 void setFooter(String text, int value) { 82 footer.text = text; 83 footer.value = value; 84 notifyDataSetChanged(); 85 } 86 87 @Override 88 public int getCount() { 89 return rowList.size() + 2; 90 } 91 @Override 92 public Object getItem(int position) { 93 switch(getItemViewType(position)) { 94 case HEADER_TYPE: return header; 95 case ROW_TYPE: return rowList.get(position-1); 96 case FOOTER_TYPE: return footer; 97 } 98 return null; 99 } 100 @Override 101 public long getItemId(int position) { 102 return position; 103 } 104 105 @Override 106 public int getViewTypeCount() { 107 return 3; 108 } 109 @Override 110 public int getItemViewType(int position) { 111 return position == 0 ? HEADER_TYPE : 112 position == rowList.size()+1 ? FOOTER_TYPE : 113 ROW_TYPE; 114 } 115 116 @Override 117 public View getView(int position, View convertView, ViewGroup parent) { 118 switch(getItemViewType(position)) { 119 case HEADER_TYPE: 120 if(convertView == null) { 121 convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false); 122 convertView.setTag(new HeaderViewHolder(convertView)); 123 } 124 HeaderViewHolder hvh = (HeaderViewHolder)convertView.getTag(); 125 hvh.text1.setText(header.text1); 126 hvh.text2.setText(header.text2); 127 return convertView; 128 case ROW_TYPE: 129 if(convertView == null) { 130 convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false); 131 convertView.setTag(new RowViewHolder(convertView)); 132 } 133 RowViewHolder rvh = (RowViewHolder)convertView.getTag(); 134 Row row = rowList.get(position - 1); 135 rvh.text1.setText(row.text1); 136 rvh.text2.setText(row.text2); 137 rvh.value.setText("" + row.value); 138 return convertView; 139 case FOOTER_TYPE: 140 if(convertView == null) { 141 convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer, parent, false); 142 convertView.setTag(new FooterViewHolder(convertView)); 143 } 144 FooterViewHolder fvh = (FooterViewHolder)convertView.getTag(); 145 fvh.text.setText(footer.text); 146 fvh.value.setText("" + footer.value); 147 return convertView; 148 } 149 return null; 150 } 151 } 152}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<ListView xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:id="@+id/listView" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".MainActivity" />

res/layout/header.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content" 6 android:background="#00ffff"> 7 <TextView 8 android:id="@+id/text1" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="header text1" 12 android:textSize="40dp" 13 app:layout_constraintStart_toStartOf="parent" 14 app:layout_constraintTop_toTopOf="parent" /> 15 <TextView 16 android:id="@+id/text2" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:text="header text2" 20 android:textSize="20dp" 21 app:layout_constraintEnd_toEndOf="parent" 22 app:layout_constraintTop_toBottomOf="@id/text1" /> 23</androidx.constraintlayout.widget.ConstraintLayout>

res/layout/row.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content"> 6 <TextView 7 android:id="@+id/text1" 8 android:layout_width="0dp" 9 android:layout_height="wrap_content" 10 android:text="row text1" 11 android:textSize="30dp" 12 app:layout_constraintEnd_toStartOf="@id/value" 13 app:layout_constraintStart_toStartOf="parent" 14 app:layout_constraintTop_toTopOf="parent" /> 15 <TextView 16 android:id="@+id/text2" 17 android:layout_width="0dp" 18 android:layout_height="wrap_content" 19 android:text="row text2" 20 android:textSize="20dp" 21 android:paddingStart="20dp" 22 app:layout_constraintEnd_toStartOf="@id/value" 23 app:layout_constraintStart_toStartOf="parent" 24 app:layout_constraintTop_toBottomOf="@id/text1" /> 25 <TextView 26 android:id="@+id/value" 27 android:layout_width="wrap_content" 28 android:layout_height="0dp" 29 android:text="row value" 30 android:textSize="30dp" 31 android:gravity="center_vertical" 32 app:layout_constraintBottom_toBottomOf="@id/text2" 33 app:layout_constraintEnd_toEndOf="parent" 34 app:layout_constraintTop_toTopOf="@id/text1" /> 35</androidx.constraintlayout.widget.ConstraintLayout>

res/layout/footer.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content" 6 android:background="#ffff00"> 7 <TextView 8 android:id="@+id/text" 9 android:layout_width="0dp" 10 android:layout_height="wrap_content" 11 android:text="footer text" 12 android:textSize="40dp" 13 app:layout_constraintEnd_toStartOf="@id/value" 14 app:layout_constraintStart_toStartOf="parent" 15 app:layout_constraintTop_toTopOf="parent" /> 16 <TextView 17 android:id="@+id/value" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:text="f-value" 21 android:textSize="40dp" 22 app:layout_constraintEnd_toEndOf="parent" 23 app:layout_constraintTop_toTopOf="parent" /> 24</androidx.constraintlayout.widget.ConstraintLayout>

実行結果
起動時
スクリーンショット
最後までスクロール時
スクリーンショット


なお、 ListView の代わりに自分で View を管理出来れば、

xml

1<LinearLayout 2 android:id="@+id/rows" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:orientation="vertical" />

というレイアウトに対して

java

1 LinearLayout rows = findViewById(R.id.rows); 2 for(int i = 1; i <= 20; i++) { 3 View view = LayoutInflater.from(this).inflate(R.layout.row, rows, false); 4 ((TextView)view.findViewById(R.id.text1)).setText("かきくけこ" + i); 5 ((TextView)view.findViewById(R.id.text2)).setText("さしすせそ" + i); 6 ((TextView)view.findViewById(R.id.value)).setText("" + (100 + i)); 7 rows.addView(view, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); 8 }

というコードで行を並べたような状態に出来ます。

投稿2023/03/24 03:06

編集2023/03/24 14:53
jimbe

総合スコア12696

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PeerGynt

2023/03/25 05:09

>jimbeさん どうもありがとうございます。 サンプルソースまで書いて下さるとは……大変恐縮しております。 早速勉強させて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問