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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Android

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

Xamarin

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

Q&A

解決済

1回答

1098閲覧

ListViewをスクロールさせるとリスト表示が崩れる

PeerGynt

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Android

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

Xamarin

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

0グッド

0クリップ

投稿2023/01/21 12:29

お世話になります。Androidアプリ開発の初心者です。
Microsoft Learn等のサイトを参考に、見様見真似で販売管理ツールを組んでいます。
以下、原因と対処法を教えて下さい。もしくは「ここが参考になる」といったサイト等、ございましたらご教示頂けると幸いです。

■問題点

ListViewを使用しているが、スクロールさせるとリスト表示が崩れる。
一度ゆっくり、下へとスクロールさせるのは問題ない。上に戻ったり再度下へスクロールさせるとダメ。

1つは普通にリストを表示しているだけ。表示アイテムはTextViewのみ。
互い違いに背景色をセットし縞状にしているが、上下にスクロールさせるとどんどん背景色が消える。

xml

1 - item_ListView1.xml 2 3<?xml version="1.0" encoding="utf-8"?> 4<LinearLayout 5 xmlns:android="http://schemas.android.com/apk/res/android" 6 android:orientation="vertical" 7 android:minWidth="25px" 8 android:minHeight="25px" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:id="@+id/linLyBack" 12 android:textAlignment="viewEnd" 13 android:paddingTop="2dp" 14 android:paddingLeft="10dp" 15 android:paddingRight="10dp"> 16 <LinearLayout 17 android:orientation="horizontal" 18 android:minWidth="25px" 19 android:minHeight="25px" 20 android:layout_marginBottom="2px" 21 android:layout_width="match_parent" 22 android:layout_height="wrap_content" 23 android:id="@+id/linearLayout2"> 24 <TextView 25 android:text="123" 26 android:textAppearance="?android:attr/textAppearanceSmall" 27 android:layout_width="0dp" 28 android:layout_height="match_parent" 29 android:layout_marginTop="3dp" 30 android:id="@+id/tvwID" 31 android:layout_weight="15" 32 android:textAlignment="viewEnd" 33 android:layout_gravity="bottom" /> 34 <TextView 35 android:text="得意先名" 36 android:textAppearance="?android:attr/textAppearanceMedium" 37 android:layout_width="0dp" 38 android:layout_height="match_parent" 39 android:paddingLeft="5dp" 40 android:id="@+id/tvwName" 41 android:layout_weight="90" 42 android:textAlignment="viewStart" 43 android:textColor="#ff000000" /> 44 </LinearLayout> 45 <TextView 46 android:text="住所" 47 android:textAppearance="?android:attr/textAppearanceSmall" 48 android:layout_width="match_parent" 49 android:layout_height="wrap_content" 50 android:id="@+id/tvwExData" 51 android:textAlignment="viewEnd" 52 android:paddingBottom="5dp" /> 53</LinearLayout> 54

C#

1 - ListAdapterの行定義箇所記述 2 3 public override View GetView(int position, View convertView, ViewGroup parent) 4 { 5 var _item = _items[position]; 6 7 View view = convertView; 8 if (view == null) 9 { 10 view = context.LayoutInflater.Inflate(Resource.Layout.item_ListView1, null); 11 } 12 13 view.FindViewById<TextView>(Resource.Id.tvwID).Text = _item.ID; 14 view.FindViewById<TextView>(Resource.Id.tvwName).Text = _item.Name; 15 view.FindViewById<TextView>(Resource.Id.tvwExData).Text = _item.ExData; 16 17 if ((position + 1) % 2 != 0) 18 { 19 view.FindViewById<LinearLayout>Resource.Id.linLyBack).SetBackgroundColor(Android.Graphics.Color.Ivory); 20 } 21 22 return view; 23 }

もう1つはページャーのフラグメント内にリストを配置。
こちらも表示アイテムはTextViewのみ。
上下にスクロールさせるとどんどんリストが崩れ、終いには行境界線だけになる。

xml

1 - item_ListView2.xml 2 3<?xml version="1.0" encoding="utf-8"?> 4<LinearLayout 5 xmlns:android="http://schemas.android.com/apk/res/android" 6 android:orientation="vertical" 7 android:minWidth="25px" 8 android:minHeight="25px" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:id="@+id/linLyTrans" 12 android:textAlignment="viewEnd" 13 android:paddingTop="2dp" 14 android:paddingLeft="10dp" 15 android:paddingRight="10dp"> 16 <TextView 17 android:text="Header" 18 android:textAppearance="?android:attr/textAppearanceSmall" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:id="@+id/tvwHeader" /> 22 <LinearLayout 23 android:id="@+id/linLyItem" 24 android:orientation="horizontal" 25 android:minWidth="25px" 26 android:minHeight="25px" 27 android:layout_marginBottom="2px" 28 android:layout_width="match_parent" 29 android:layout_height="wrap_content" 30 android:paddingLeft="10dp"> 31 <TextView 32 android:text="Item" 33 android:textAppearance="?android:attr/textAppearanceSmall" 34 android:layout_width="0dp" 35 android:layout_height="wrap_content" 36 android:id="@+id/tvwItem" 37 android:layout_weight="8.5" 38 android:paddingLeft="15dp" /> 39 </LinearLayout> 40 <LinearLayout 41 android:orientation="horizontal" 42 android:minWidth="25px" 43 android:minHeight="25px" 44 android:layout_marginBottom="2px" 45 android:layout_width="match_parent" 46 android:layout_height="wrap_content" 47 android:id="@+id/linLyDtl" 48 android:paddingLeft="10dp"> 49 <TextView 50 android:text="1234" 51 android:textAppearance="?android:attr/textAppearanceSmall" 52 android:layout_width="0dp" 53 android:layout_height="match_parent" 54 android:layout_marginTop="3dp" 55 android:id="@+id/tvwQuantity" 56 android:layout_weight="1" 57 android:textAlignment="viewEnd" 58 android:layout_gravity="right" /> 59 <TextView 60 android:text="23,456" 61 android:textAppearance="?android:attr/textAppearanceSmall" 62 android:layout_width="0dp" 63 android:layout_height="match_parent" 64 android:layout_marginTop="3dp" 65 android:id="@+id/tvwUnit" 66 android:layout_weight="1" 67 android:textAlignment="viewEnd" 68 android:layout_gravity="right" /> 69 <TextView 70 android:text="345,678" 71 android:textAppearance="?android:attr/textAppearanceSmall" 72 android:layout_width="0dp" 73 android:layout_height="match_parent" 74 android:layout_marginTop="3dp" 75 android:id="@+id/tvwEarning" 76 android:layout_weight="1" 77 android:textAlignment="viewEnd" 78 android:layout_gravity="right" /> 79 <TextView 80 android:text="456,789" 81 android:textAppearance="?android:attr/textAppearanceSmall" 82 android:layout_width="0dp" 83 android:layout_height="match_parent" 84 android:layout_marginTop="3dp" 85 android:id="@+id/tvwPayment" 86 android:layout_weight="1" 87 android:textAlignment="viewEnd" 88 android:layout_gravity="right" /> 89 <TextView 90 android:text="567,890" 91 android:textAppearance="?android:attr/textAppearanceSmall" 92 android:layout_width="0dp" 93 android:layout_height="match_parent" 94 android:layout_marginTop="3dp" 95 android:id="@+id/tvwBalance" 96 android:layout_weight="1" 97 android:textAlignment="viewEnd" 98 android:layout_gravity="right" /> 99 </LinearLayout> 100</LinearLayout> 101

C#

1 - ListAdapterの行定義箇所記述 2 3public override View GetView(int position, View convertView, ViewGroup parent) 4 { 5 var _item = _items[position]; 6 7 View view = convertView; 8 if (view == null) 9 { 10 view = context.LayoutInflater.Inflate(Resource.Layout.item_ListView2, null); 11 } 12 13 view.FindViewById<TextView>(Resource.Id.tvwHeader).Text = _item.Header; 14 view.FindViewById<TextView>(Resource.Id.tvwItem).Text = _item.Name; 15 view.FindViewById<TextView>(Resource.Id.tvwQuantity).Text = _item.Quantity; 16 view.FindViewById<TextView>(Resource.Id.tvwUnit).Text = _item.Unit; 17 view.FindViewById<TextView>(Resource.Id.tvwEarning).Text = _item.Earning; 18 view.FindViewById<TextView>(Resource.Id.tvwPayment).Text = _item.Payment; 19 view.FindViewById<TextView>(Resource.Id.tvwBalance).Text = _item.Balance; 20 21 switch (_item.Division) 22 { 23 case TransFields.Div.Hdr: 24 view.FindViewById<LinearLayout>(Resource.Id.linLyItem).Visibility = ViewStates.Gone; 25 view.FindViewById<LinearLayout>(Resource.Id.linLyDtl).Visibility = ViewStates.Gone; 26 break; 27 case TransFields.Div.Item: 28 view.FindViewById<TextView>(Resource.Id.tvwHeader).Visibility = ViewStates.Gone; 29 view.FindViewById<LinearLayout>(Resource.Id.linLyDtl).Visibility = ViewStates.Gone; 30 break; 31 default: 32 view.FindViewById<TextView>(Resource.Id.tvwHeader).Visibility = ViewStates.Gone; 33 view.FindViewById<LinearLayout>(Resource.Id.linLyItem).Visibility = ViewStates.Gone; 34 break; 35 } 36 37 return view; 38 }

■開発環境等

Xamarin.Androidプロジェクト
最小Android 9.0(API28) ~ ターゲットAndroid 11.0(API30)
Win11 Pro + Visual Studio 2019(開発環境)
Android9.0タブレット RAM2GB(実機テスト端末)

■お聞きしたいこと

そもそも何が原因なのかが不明で、頭を抱え込んでおります。
ネットで情報をあさると「リサイクル」という言葉が時折出てくるので、何かリソースの再利用でもやっていてそれが悪さをしているのでしょうか。

原因、対処法、その他参考情報でも何でも結構ですので、ご教示頂きたいと思います。
よろしくお願いします。

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

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

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

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

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

jimbe

2023/01/23 04:52 編集

>何かリソースの再利用でもやっていて GetView が返した view は表示されなくなった時にキャッシュされ、新たな行の表示が必要になると GetView の ConvertView パラメータとして渡されて再利用する形になります。 行ビューを再利用する https://learn.microsoft.com/ja-jp/xamarin/android/user-interface/layouts/list-view/populating#row-view-re-use 従って渡された View はその前に使われた状態のままであって設定されている文字列や背景色、表示状態がどうなっているかは想定できず、一つ目の背景色や二つ目のヘッダー等の表示状態は初期状態からの変化では無く、全ての設定を行う必要があります。
jimbe

2023/01/23 05:07

ほぼ質問と関係無いですが、行レイアウトが特定のデータ(Division)によって全く異なるのであれば、 BaseAdapter の ViewType 関係のメソッドをオーバーライドすることで複数のレイアウトを持たせることが出来ると思います (xamarin の BaseAdapter のドキュメントが見つからず)。 Visivirity を操作する必要が無くなる程度で、 GetView でソレに合わせてデータを設定する(無いビューに設定しないようにする)必要があるのは変わりませんが。
guest

回答1

0

自己解決

済みません。自己解決しました。
convertView の中身がNullの場合のみ、view定義すべきなんですね。
大変失礼致しました。

投稿2023/01/21 13:11

PeerGynt

総合スコア8

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

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

jimbe

2023/01/21 16:06

>convertView の中身がNullの場合のみ、view定義すべきなんですね どちらの GetView にも View view = convertView; if (view == null) { view = context.LayoutInflater.Inflate(~); } はありますけど・・・これのことでは無いのでしょうか。
PeerGynt

2023/01/22 06:48

>jimbeさん コメントありがとうございます。 そうです、それです。 サンプルソースを参考に記述し、ミスっているんだけどちゃんと仕組みが分かっていないからミスに気付かず。 このGetViewというのは何度もコールされて(そこはデバッグで気づいていた)、そのうち大概は引数convertViewをそのまま返せばよかったようで。 ともあれ一発解決で助かりました。大変お騒がせ致しました。
jimbe

2023/01/23 04:29 編集

>そうです、それです。 >サンプルソースを参考に記述し、ミスっているんだけどちゃんと仕組みが分かっていないからミスに気付かず。 いえ、ええと、ご質問のコードをどう修正して解決になったのかが分からないのですが。 該当 if 文が「convertView の中身がNullの場合のみ、view定義」をしているように見えるのですが、問題発生時は無かったということでしょうか。 お時間ありましたら、どの部分をどう直されたのか、回答に修正後のコードをご提示頂けますか。 4-2. どのように解決したのかを伝えましょう https://teratail.com/help/question-tips#questionTips42 >あなたがどのように解決したかを書き残しておくことで、あなたの質問は貴重なコンテンツ資産となります。 >いつか他の誰かがあなたと同じ問題に陥った時、そのコンテンツにたどり着いたらすぐに解決できるように情報を残しておいてあげてください。
PeerGynt

2023/01/23 08:15

>jimbeさん ご指摘ありがとうございます。 一旦自己解決としたのですが、実は全然解決していませんでした。一体何を確認したんだか……(自己嫌悪) それでいろいろと悪あがきをしていたら、結局どうにか意図通りに動作するようになりまして。 といってもconvertViewのnullチェックを省いただけなのですが。 とはいえそれで正解とも思えないし、さりとて現時点で不都合も生じていないので、様子見状態です。 この件、落ち着いてから再度検証し、必要とあらば結果をここに残しておこうと思います。いましばらくお時間を下さい。
PeerGynt

2023/03/11 04:31

大変遅くなりましたが、修正内容です。 大まかに説明した通りではありますが、要するに前掲ソース「ListAdapterの行定義箇所記述」中、8~11をカットしています。 つまり行のデザイン定義を求められた時、viewがnullなら定義、nullでなければリサイクル……ではなく、 「毎回必ず当該行のviewを定義してやる」と変更。それだけです。 私の今回の案件では、リスト行数は多くても100弱、画像やアイコン表示なし、導入実機のスペックも上々なので、これでなんの問題もないようです。 現時点で1ヶ月半程、前述の対処で様子を見ていますが、特に問題は起きていません。 他の画面では数百行のリストビューをページャーで切り替えながら表示させる、という結構ヘビーな処理を行っていますが、こちらも問題なく動いています。敢えて画面リソースのリサイクル機能に頼らなくてもいいし、今回の場合はむしろ、頼るから不具合発生していたようです(ここが謎ですが) 追加報告、以上です。色々とアドバイスを下さった方々、どうもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問