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

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

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

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Q&A

2回答

4632閲覧

【Android】ListViewのアイテムが更新されない

sarukasi

総合スコア8

Android

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

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

0グッド

0クリップ

投稿2016/09/10 03:25

###前提・実現したいこと
Twitter4Jを使用してAndroidアプリを作成し、TwitterのStreamingAPIにて受信したツイートのユーザ名と本文をListViewに追加したいです。
その際、新しいツイートをListViewの一番上に追加し、その新しく追加したアイテムが画面の一番上に来るようにスクロールしたいです。

###発生している問題・エラーメッセージ

ツイートを受信した後、スクロールするまでListViewのアイテムが更新されません。
手動でListViewをスクロールするとListViewの内容が更新されます。

###該当のソースコード

package com.example.twitest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.ListView; import twitter4j.*; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder; public class MainActivity extends AppCompatActivity { private static final String CONSUMER_KEY = "***"; private static final String CONSUMER_SECRET = "***"; private static final String ACCESS_TOKEN = "***"; private static final String ACCESS_TOKEN_SECRET = "***"; static ArrayAdapter<String> adapter; static ListView lv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); lv = (ListView)findViewById(R.id.listView); lv.setAdapter(adapter); Configuration conf = new ConfigurationBuilder().setOAuthConsumerKey(CONSUMER_KEY) .setOAuthConsumerSecret(CONSUMER_SECRET).setOAuthAccessToken(ACCESS_TOKEN) .setOAuthAccessTokenSecret(ACCESS_TOKEN_SECRET).build(); TwitterStream twStream = new TwitterStreamFactory(conf).getInstance(); twStream.addListener(new MyStatusListener()); twStream.sample(); } static class MyStatusListener implements StatusListener{ @Override public void onStatus(Status status) { //ツイートを受信した際の処理 //受信したツイートのユーザーネームと本文を取得 String username = status.getUser().getScreenName(); String text = status.getText(); //一番上にユーザーネームと本文の入ったアイテムを追加 adapter.insert("UserName:" + username + " / Text:" + text,0); //adapterに変更を通知する adapter.notifyDataSetChanged(); //ListViewを更新 lv.invalidateViews(); //一番上のアイテムを選択し、画面を上にスクロールする lv.setSelection(0); Log.v("Text:",text); } @Override public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { } @Override public void onTrackLimitationNotice(int i) { } @Override public void onScrubGeo(long l, long l1) { } @Override public void onStallWarning(StallWarning stallWarning) { } @Override public void onException(Exception e) { } } }

###試したこと
・ログにはStreamingで受信したツイートが止まらずに流れてくるので、ツイートの受信自体は問題無くできているはずです。

###補足情報(言語/FW/ツール等のバージョンなど)

エミュレータ(Nexus5 Android5.1.1)上で実行しています

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

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

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

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

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

guest

回答2

0

曖昧な記憶での回答で申し訳ないですがStatusListenerのonStatusメソッドなどは非同期スレッドで呼ばれているのでUIスレッドで生成したHandlerにUI処理をpostするというのはどうでしょうか?

投稿2016/10/13 04:53

meilcli

総合スコア132

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

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

0

最初に空のリストを表示しているからかもしれないですね。
試しに適当な文字列を追加した状態で表示するとどうでしょうか。

投稿2016/09/10 04:15

yona

総合スコア18155

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

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

sarukasi

2016/09/10 04:51

ありがとうございます。 adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); とadapterを宣言した次の行でadapter.add("hoge")のようにアイテムを一つ追加してみましたが、最初に表示される"hoge"アイテムが一つ増えただけで他の動作は変わりませんでした。
yona

2016/09/10 05:01

そういえば、特定のバージョンでArrayAdapter#notifyDataSetChangedが効かないことがありました。 リストに行が増えることにArrayAdapterをセットし直して対処した覚えがあります。
sarukasi

2016/09/10 06:24

ありがとうございます。 notifyDataSetChangedの代わりにlv.setAdapterとしてみた所、その部分でエラーとなり、ログを出してみたところ以下のようなエラーが発生しました。 E/ERROR: java.lang.IllegalStateException: Observer android.widget.AbsListView$AdapterDataSetObserver@1e99cc9 was not registered. このエラーについてarrayAdapterを何度も繰り返しsetすると起こることがあるとの情報が見つかり、全世界のツイートではなく1ユーザーのタイムラインを取得して取得の頻度を下げるようにしたところ、新しいツイートを取得するとListViewの表示が消えて画面が真っ白になり、スクロール操作をすると更新済みのListViewが表示されるという状態になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問