どのようにリフレッシュAndroid listview?
-
20-09-2019 - |
質問
どのようにリフレッシュアンドロイド ListView
後の追加/削除する動的データはもらえますか?
解決
もし一度ごnotifyDataSetChanged()
オブジェクト上で Adapter
に呼び出し「は、アダプタ内のデータを変更しまし。
どのように/ notifyDataSetChanged()
を呼び出すためにいくつかの追加の詳細は、私は<のhref =「http://www.youtube.com/watch?v=wDBM6wVEO70&t=17m38s」のrel =「noreferrer」タイトル= "グーグルで見ることができます/ O 2010 - 。リストビューの世界 ">このGoogle I / Oビデオの
他のヒント
また、あなたはこれを使用することができます:
myListView.invalidateViews();
は無視してくださいすべての invalidate()
, invalidateViews()
, requestLayout()
,...この答えます。
とは自分がすべきことなのだといい、幸いにも、正解) 電話 notifyDataSetChanged()
御アダプター.
トラブ
場合に呼び出し notifyDataSetChanged()
動作しないすべてのレイアウト方法になります。今回の ListView
が適切に更新されます。失敗した場合の差を確認する必要があるが、データアダプターが出ているのです。
これだけの収集だけを記憶したことを確認するには実際に削除または追加のコレクションに呼び出す前に notifyDataSetChanged()
.
だんのデータベースやサービスのバックエンドかできないメソッドを呼び出しを取得する情報を再度操作、メモリデータ呼び出す前に notifyDataSetChanged()
.
このことがこの notifyDataSetChanged
仕様は、場合によってはデータセットが変わりました。この場所を見ていない場合は変更してデバッグが必要です。
ArrayAdapter vs BaseAdapter
見つかるとアダプタをまとめて見ることができる管理のようにBaseAdapterにしようとしています。一部のアダプターのようにArrayAdapterて管理収集い、硬めの適切な収集しました。でもでも超が困難なことが多いです。
UIのスレッド
ここを呼び出すことができるのUI。その他の答えの例をどのように達成します。ただし、これは必要なまさんにもこれらの情報外部からのUI。ることから、サービス以外のUI。シンプルにケーされますの更新のデータからボタンをクリックまたは他の活動/fragment.でも、UI。必要なもポップたrunOnUiTrheadます。
クンプルプロジェクト
き https://github.com/hanscappelle/so-2250770.git.でクローンのプロジェクトにAndroidスタジオ(gradle).このプロジェクトはMainAcitivity築 ListView
すべてのランダムなデータです。このリストもリフレッシュでき用のメニューです。
このアダプタ実装を作成したこの例ではModelObject公開のデータ収集
public class MyListAdapter extends BaseAdapter {
/**
* this is our own collection of data, can be anything we
* want it to be as long as we get the abstract methods
* implemented using this data and work on this data
* (see getter) you should be fine
*/
private List<ModelObject> mData;
/**
* our ctor for this adapter, we'll accept all the things
* we need here
*
* @param mData
*/
public MyListAdapter(final Context context, final List<ModelObject> mData) {
this.mData = mData;
this.mContext = context;
}
public List<ModelObject> getData() {
return mData;
}
// implement all abstract methods here
}
コードから、MainActivity
public class MainActivity extends Activity {
private MyListAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list = (ListView) findViewById(R.id.list);
// create some dummy data here
List<ModelObject> objects = getRandomData();
// and put it into an adapter for the list
mAdapter = new MyListAdapter(this, objects);
list.setAdapter(mAdapter);
// mAdapter is available in the helper methods below and the
// data will be updated based on action menu interactions
// you could also keep the reference to the android ListView
// object instead and use the {@link ListView#getAdapter()}
// method instead. However you would have to cast that adapter
// to your own instance every time
}
/**
* helper to show what happens when all data is new
*/
private void reloadAllData(){
// get new modified random data
List<ModelObject> objects = getRandomData();
// update data in our adapter
mAdapter.getData().clear();
mAdapter.getData().addAll(objects);
// fire the event
mAdapter.notifyDataSetChanged();
}
/**
* helper to show how only changing properties of data
* elements also works
*/
private void scrambleChecked(){
Random random = new Random();
// update data in our adapter, iterate all objects and
// resetting the checked option
for( ModelObject mo : mAdapter.getData()) {
mo.setChecked(random.nextBoolean());
}
// fire the event
mAdapter.notifyDataSetChanged();
}
}
詳細情報
他のイベントではメインの力についてlistViewsはこちら: http://www.vogella.com/articles/AndroidListView/article.html
あなたはいつでも実行可能な呼び出します:
runOnUiThread(run);
OnCreate()
、あなたの実行可能なスレッドを設定します:
run = new Runnable() {
public void run() {
//reload content
arraylist.clear();
arraylist.addAll(db.readAll());
adapter.notifyDataSetChanged();
listview.invalidateViews();
listview.refreshDrawableState();
}
};
私は私のリストビューの動的更新のいくつかの問題を持っています。
あなたのアダプタにnotifyDataSetChanged()を呼び出します。
どのように/ notifyDataSetChangedを(コールするにいくつかの追加の詳細を)このGoogle I / Oのビデオで見ることができます。
notifyDataSetChanged()[私は別のクラスからnotifyDataSetChangedと呼ば]私の場合には正常に動作しませんでした。念のために私は、実行中の活動(スレッド)でのListViewを編集しました。そのビデオクリストファーのおかげで、最終的なヒントを与えます。
私の第二のクラスでは私が使用した
Runnable run = new Runnable(){
public void run(){
contactsActivity.update();
}
};
contactsActivity.runOnUiThread(run);
私の活動から)(更新をアクセスもできます。このアップデートには含まれて
myAdapter.notifyDataSetChanged();
ビューをリフレッシュするためにアダプタを指示します。 限り私が言うことができますとしてうまく働いています。
ご利用の場合 SimpleCursorAdapter み呼び出し requery() のカーソルオブジェクトです。
あなたはまだListViewの元気回復に満足していない場合、あなたはこのスニペットを見ることができ、これはDBからリストビューをロードするためのもので、実際に何をしなければならないことは、単純に、リストビューをリロードされます そのない最高のコードへの道が、あなたが望むようにそれがリストビューを更新します..
これは、uは、より良い解決策を見つけた場合、共有してください...
....私の作品....... ...... do your CRUD Operations.. ...... ..... DBAdapter.open(); DBAdapter.insert_into_SingleList(); // Bring that DB_results and add it to list as its contents.... ls2.setAdapter(new ArrayAdapter(DynTABSample.this, android.R.layout.simple_list_item_1, DBAdapter.DB_ListView)); DBAdapter.close();
この記事で人によって提案された解決策は、あなたのデバイスのAndroidのバージョンに応じて、主に動作しますか。例のaddAllメソッドを使用するには、あなたは、Android配置する必要があり:あなたのAndroidデバイスにminSdkVersionが=「10」
私は、アダプタに自身の方法で私を作成しているすべてのデバイスのためにこの質問を解決し、追加の内部で使用してメソッドを削除するには問題なく、あなたがデータその更新ArrayAdapterを継承します。
マイコード:私自身のデータクラスRaceResultを使用して、独自のデータモデルを使用する
。ResultGpRowAdapter.java
public class ResultGpRowAdapter extends ArrayAdapter<RaceResult> {
Context context;
int resource;
List<RaceResult> data=null;
public ResultGpRowAdapter(Context context, int resource, List<RaceResult> objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.data = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
........
}
//my own method to populate data
public void myAddAll(List<RaceResult> items) {
for (RaceResult item:items){
super.add(item);
}
}
ResultsGp.java
public class ResultsGp extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...........
...........
ListView list = (ListView)findViewById(R.id.resultsGpList);
ResultGpRowAdapter adapter = new ResultGpRowAdapter(this, R.layout.activity_result_gp_row, new ArrayList<RaceResult>()); //Empty data
list.setAdapter(adapter);
....
....
....
//LOAD a ArrayList<RaceResult> with data
ArrayList<RaceResult> data = new ArrayList<RaceResult>();
data.add(new RaceResult(....));
data.add(new RaceResult(....));
.......
adapter.myAddAll(data); //Your list will be udpdated!!!
あなたが更新すると、あなたのスクロール位置を維持したい、とあなたがこれを行うことができた場合:
if (mEventListView.getAdapter() == null) {
EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
mEventListView.setAdapter(eventLogAdapter);
} else {
((EventLogAdapter)mEventListView.getAdapter()).refill(events);
}
public void refill(List<EventLog> events) {
mEvents.clear();
mEvents.addAll(events);
notifyDataSetChanged();
}
詳細情報については、以下を参照してください。<のhref = "http://vikinghammer.com/2011/06/17/android-listview-maintain-your-scroll-position-when-you-refresh/" のrel = "nofollowを"> AndroidのListViewコントロール:あなたがに更新すると、あなたのスクロール位置を維持
ただ、リスナーの内側myArrayList.remove(position);
を使用します:
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, android.view.View view, int position, long id) {
myArrayList.remove(position);
myArrayAdapter.notifyDataSetChanged();
}
});
あなたがListView
に膨らまされているリストwhooseデータの単一のオブジェクトを使用する必要があります。参照が変更されている場合は、リストビューから要素を削除する.Wheneverその後、does't作業をnotifyDataSetChanged()
もあなたはそれがArrayListを<>またはその後、何か他のコールであるかどうかを使用しているリストから削除します
お使いのアダプタクラスのオブジェクトにnotifyDataSetChanged()
ます。
だからここに私は私のアダプターでそれを管理する方法について
以下を参照してくださいpublic class CountryCodeListAdapter extends BaseAdapter implements OnItemClickListener{
private Context context;
private ArrayList<CountryDataObject> dObj;
private ViewHolder holder;
private Typeface itemFont;
private int selectedPosition=-1;
private ArrayList<CountryDataObject> completeList;
public CountryCodeListAdapter(Context context, ArrayList<CountryDataObject> dObj) {
this.context = context;
this.dObj=dObj;
completeList=new ArrayList<CountryDataObject>();
completeList.addAll(dObj);
itemFont=Typeface.createFromAsset(context.getAssets(), "CaviarDreams.ttf");
}
@Override
public int getCount() {
return dObj.size();
}
@Override
public Object getItem(int position) {
return dObj.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if(view==null){
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.states_inflator_layout, null);
holder.textView = ((TextView)view.findViewById(R.id.stateNameInflator));
holder.checkImg=(ImageView)view.findViewById(R.id.checkBoxState);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(dObj.get(position).getCountryName());
holder.textView.setTypeface(itemFont);
if(position==selectedPosition)
{
holder.checkImg.setImageResource(R.drawable.check);
}
else
{
holder.checkImg.setImageResource(R.drawable.uncheck);
}
return view;
}
private class ViewHolder{
private TextView textView;
private ImageView checkImg;
}
public void getFilter(String name) {
dObj.clear();
if(!name.equals("")){
for (CountryDataObject item : completeList) {
if(item.getCountryName().toLowerCase().startsWith(name.toLowerCase(),0)){
dObj.add(item);
}
}
}
else {
dObj.addAll(completeList);
}
selectedPosition=-1;
notifyDataSetChanged();
notifyDataSetInvalidated();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Registration reg=(Registration)context;
selectedPosition=position;
reg.setSelectedCountryCode("+"+dObj.get(position).getCountryCode());
notifyDataSetChanged();
}
}
リストビューからデータを削除した後、あなたはrefreshDrawableState()
を呼び出す必要があります。
ここでは例があります:
final DatabaseHelper db = new DatabaseHelper (ActivityName.this);
db.open();
db.deleteContact(arg3);
mListView.refreshDrawableState();
db.close();
とdeleteContact
クラスのDatabaseHelper
の方法は多少
public boolean deleteContact(long rowId) {
return db.delete(TABLE_NAME, BaseColumns._ID + "=" + rowId, null) > 0;
}
私は自分のSimpleAdapterを更新する上で動作するように)notifyDataSetChangedを(得ることができなかったので、代わりに私が最初にListViewコントロールを追加し、その後、)(removeAllViewsを使用して親のレイアウトに接続されたすべてのビューを削除し、それが働いていた、私にできるようにしようとしましたUIを更新します:
LinearLayout results = (LinearLayout)findViewById(R.id.results);
ListView lv = new ListView(this);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter( this, list, R.layout.directory_row,
new String[] { "name", "dept" }, new int[] { R.id.name, R.id.dept } );
for (...) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", name);
map.put("dept", dept);
list.add(map);
}
lv.setAdapter(adapter);
results.removeAllViews();
results.addView(lv);
私にとっては、リストビューを更新することができ、SQLデータベース何の情報を変更した後、(特定の拡張可能なリストビューを可能にする)のでnotifyDataSetChanged()が解決しない場合は、最初にあなたのリストをクリアし、その呼び出しの後に再度追加しようとすることができますnotifyDataSetChanged ()。たとえば、
private List<List<SomeNewArray>> arrayList;
List<SomeNewArray> array1= getArrayList(...);
List<SomeNewArray> array2= getArrayList(...);
arrayList.clear();
arrayList.add(array1);
arrayList.add(array2);
notifyDataSetChanged();
それはあなたのために理にかなって願っています。
SimpleCursorAdapterを使用している間は、アダプタ上changeCursor(newCursor)を呼び出すことができます。
Iは同じであった。
私がやったことは、このました
public class Fragment01 extends android.support.v4.app.Fragment implements ...
{
private ListView listView;
private ArrayAdapter<String> arrayAdapter_string;
...
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
...
this.listView= (ListView) super.getActivity().findViewById(R.id.fragment01_listView);
...
this.arrayAdapter_string= new ArrayAdapter<String>(super.getActivity(), R.layout.dispositivo_ble_item, R.id.fragment01_item_textView_titulo);
this.listView.setAdapter(this.arrayAdapter_string);
}
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
...
super.getActivity().runOnUiThread(new RefreshListView(device));
}
private class RefreshListView implements Runnable
{
private BluetoothDevice bluetoothDevice;
public RefreshListView(BluetoothDevice bluetoothDevice)
{
this.bluetoothDevice= bluetoothDevice;
}
@Override
public void run()
{
Fragment01.this.arrayAdapter_string.add(new String(bluetoothDevice.toString()));
Fragment01.this.arrayAdapter_string.notifyDataSetChanged();
}
}
次に、リストビューを動的に検出されたデバイスのMACアドレスを取り込むようになりました。
私はそれはあなたがリフレッシュによって何を意味するかに依存だと思います。あなたは、GUI表示をリフレッシュする必要があることを意味するか、またはあなたが子ビューを使用すると、プログラム的getChildAt(int)を呼び出し、アダプタにあるものに対応するビューを取得できるように更新する必要があることを意味しています。
あなたはGUI表示をリフレッシュしたい場合は、、その後、アダプタ上notifyDataSetChanged()を呼び出します。 GUIは、次の再描画に更新されます。
あなたは、getChildAt(int)を呼び出し、アダプタにあるものが何であるかを反映したビューを取得することができるようにしたい場合は、layoutChildren()への呼び出し。これは、子ビューは、アダプタデータから再構成されるようになります。
私は私がリストビューに表示したいのArrayListを持っていました。 ArrayListのは、MySQLからの要素を含んでいました。 私はこの方法をonRefreshオーバーライドし、その方法では、私はのtablelayout.removeAllViews()を使用し、を、データベースから再度データを取得するためのプロセスを繰り返します。 しかし、その前に、あなたのArrayListまたは任意のデータstructreや他の新しいデータが古いものに追加されますをクリアすることを確認してください..
は、その後、自分のメインの活動に静的なアダプタを作成し、次の操作を行います。
@Override
public void onDestroy() {
if (MainActivity.isInFront == true) {
if (MainActivity.adapter != null) {
MainActivity.adapter.notifyDataSetChanged();
}
MainActivity.listView.setAdapter(MainActivity.adapter);
}
}
あなたは、Androidのガイド線で行っている、あなたはContentProviders
からデータを取得するためにDatabase
を使用していて、ListView
とCursorLoader
を使用してCursorAdapters
でそれを表示している場合、関連するデータへのあなたのすべての変更が自動的に反映されますリストビューます。
getContext().getContentResolver().notifyChange(uri, null);
でカーソル上のあなたのContentProvider
は周りの余分な作業を必要と.NO変更を反映するのに十分なされます。
しかし、あなたは、これらすべてのを使用していないとき、あなたはデータセットが変更された場合はアダプターを伝える必要があります。また、あなたは再移入/データセットをリロードする必要があります(リストを言う)、その後、あなたは、アダプタにnotifyDataSetChanged()
を呼び出す必要があります。
notifyDataSetChanged()
wont作品。
ここでは、ドキュメント内の方法上記のコメントがある -
/**
* Notifies the attached observers that the underlying data has been changed
* and any View reflecting the data set should refresh itself.
*/
私は唯一のそのようにのような呼び出しを行う、リストビュー用のアダプタをリセットし、新しいアダプタのデータを取得することによってnotifyDataSetChangedを得ることができた。
expandableAdapter = baseFragmentParent.setupEXLVAdapter();
baseFragmentParent.setAdapter(expandableAdapter);
expandableAdapter.notifyDataSetChanged();
他のオプションには、onWindowFocusChanged
方法ですが、確かにその敏感と興味がある人のためのいくつかの余分なコーディングを必要とする
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
// some controls needed
programList = usersDBHelper.readProgram(model.title!!)
notesAdapter = DailyAdapter(this, programList)
notesAdapter.notifyDataSetChanged()
listview_act_daily.adapter = notesAdapter
}
あなたのアダプターにリストを渡したことを検討してください。
用途:
list.getAdapter().notifyDataSetChanged()
あなたのリストを更新します。
ばいかたについて紹介しましたマシナリオをここで、上記の回答をまたがった活動の一覧を表示db値と削除ボタンと削除ボタンが押されなかったり、削除する項目をクリックします。
涼をもたなかったのに使用recyclerビューが簡単なリストビュー、リストビューを初期化し、アダプタクラスです。なので、呼び出し notifyDataSetChanged()
は何もしなくなりますの内部アダプタクラスでの活動クラスがアダプタのオブジェクトが初期化されたので削除方法のアダプタクラスです。
そのソリューションしたオブジェクトを削除しますからアダプタの、アダプタの、アダプタクラス getView
の方法だけを削除する特定のオブジェクトを削除したい場合には、すべてのコ clear()
).
まあ、どったコード、
public class WordAdapter extends ArrayAdapter<Word> {
Context context;
public WordAdapter(Activity context, ArrayList<Word> words) {}
//.......
@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup group) {
//.......
ImageButton deleteBt = listItemView.findViewById(R.id.word_delete_bt);
deleteBt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (vocabDb.deleteWord(currentWord.id)) {
//.....
} else{
//.....
}
remove(getItem(position)); // <---- here is the trick ---<
//clear() // if you want to clear everything
}
});
//....
注意:こちらの remove()
や getItem()
法の継承からのアダプタクラスです。
remove()
-除去の特定の項目をクリックするgetItem(position)
-の項目(ここでは、私が私のWordのオブジェクト このリストからのクリックします。
このようにのんびりとセットにアダプター listviewの活動クラス
ArrayList<Word> wordList = new ArrayList();
WordAdapter adapter = new WordAdapter(this, wordList);
ListView list_view = (ListView) findViewById(R.id.activity_view_words);
list_view.setAdapter(adapter);
最も簡単にはちょうど新しいアダプタを作成し、古いものをドロップすることです。
myListView.setAdapter(new MyListAdapter(...));