質問

どのようにリフレッシュアンドロイド 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() のカーソルオブジェクトです。

あなたが任意のCRUD操作を実行した後、

あなたはまだ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)を呼び出すことができます。

断片に、私はいくつかの時間にわたって走査BLEデバイスのMACアドレスを持つ(単一のTextViewで)リストビューを取り込みたいと思ったときに、

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や他の新しいデータが古いものに追加されますをクリアすることを確認してください..

あなたがサービスからUIのリストビューを更新したい場合は、

は、その後、自分のメインの活動に静的なアダプタを作成し、次の操作を行います。

@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    

あなたは、Androidのガイド線で行っている、あなたはContentProvidersからデータを取得するためにDatabaseを使用していて、ListViewCursorLoaderを使用してCursorAdaptersでそれを表示している場合、関連するデータへのあなたのすべての変更が自動的に反映されますリストビューます。

getContext().getContentResolver().notifyChange(uri, null);でカーソル上のあなたのContentProviderは周りの余分な作業を必要と.NO変更を反映するのに十分なされます。

しかし、あなたは、これらすべてのを使用していないとき、あなたはデータセットが変更された場合はアダプターを伝える必要があります。また、あなたは再移入/データセットをリロードする必要があります(リストを言う)、その後、あなたは、アダプタにnotifyDataSetChanged()を呼び出す必要があります。

DATSETには変化がない場合は、

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(...));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top