안드로이드 목록보기를 새로 고치는 방법?


436

ListView동적 데이터를 추가 / 삭제 한 후 Android를 새로 고치는 방법은 무엇입니까?


3
다른 솔루션이 작동하지 않으면 refreshDrawableState를 시도하십시오. 소품합니다 stackoverflow.com/questions/5186359/...
에드윈 에반스에게

도움이 될 수 있습니다. stackoverflow.com/a/17333384/596555
끓인 물

여기 tutorialkart.com/kotlin-android/… 가 도움이 될 것입니다.
Mallikarjun M

답변:


530

해당 어댑터의 데이터를 수정 한 후 객체를 호출 notifyDataSetChanged()하십시오 Adapter.

전화 방법 / 통화 방법에 대한 추가 정보 notifyDataSetChanged()이 Google I / O 비디오 에서 볼 수 있습니다 .


24
UI 스레드에서 실행해야합니다. UI 스레드 내에서 핸들러를 만든 다음 여기에 Runable을 게시
키릴 쿨라 코브

11
다시 한번 : notifyDataSetChanged ()는 권장되는 (사용되지 않는 읽기) 사용 사례에는 적어도 작동하지 않습니다. listview, 커서 어댑터 및 컨텐츠 제공자를 사용하는 경우 gettLoaderManager (). restartLoader () 행을 따라 무언가를 시도 할 수 있습니다. 참조 : stackoverflow.com/a/19657500/1087411가 나는 notifyDataSetChanged에 적어도 일부 문서를보고 싶습니다 (). 안드로이드에서 블랙 박스 테스트까지 남아 있습니다.
앤더슨

notifyDataSetChanged가 작동하지 않으면, 당신이 잘못하고있는 사람입니다.
zdarsky.peter

4
notifyDataSetChanged가 항상 작동하지는 않습니다. 왜 이것이 논쟁인지 잘 모르겠습니다. 때때로 이전 뷰를 지우려면 listView.setAdapter (adapter)를 호출해야합니다. 또한보십시오 : stackoverflow.com/a/16261588/153275

1
notifyDataSetChanged가 작동하지 못했습니다. 어댑터에 공급 한 컬렉션이 변경되었지만 (요소가 제거됨) notifyDataSetChanged가 아무 작업도 수행하지 않았 음을 분명히 알 수있었습니다. 이 방법이 잘못되었는지 확실하지 않습니까?
byemute

204

또한 이것을 사용할 수 있습니다 :

myListView.invalidateViews();

22
보기를 다시 그리기 만하면되는 정답입니다. 예를 들어, 사용자 로그인이 발생한 후 listView의 각보기 내에 더 많은 정보 나 옵션을 표시해야합니다. 그것이 내가해야 할 일이므로 투표권을 부여했습니다. 기본 데이터가 변경되면 notifyDataSetChanged ()를 사용하는 것이 좋습니다.
SBerg413

실제로 invalidateViews()소스 코드 세트에 mDataChanged = true;있으므로 다음과 비교하여 더 나은 성능을 notifyDataSetChanged()
낼지

당신은 내 하루를 구 했어요 친구!
oskarko

당신은 "관측 가능한 목록"인 목록의 유형을 취할 수 있으며, 변경된 데이터 셋을 알 필요가 없습니다
Priya

153

모든 무시하십시오 invalidate(), invalidateViews(), requestLayout()이 질문에 대한 ... 답변을.

올바른 일을 할 (그리고 다행히도도 정답으로 표시)하는 것입니다 전화 notifyDataSetChanged()어댑터에 .

문제 해결

호출 notifyDataSetChanged()이 작동하지 않으면 모든 레이아웃 방법이 도움이되지 않습니다. 나를 ListView제대로 업데이트 했다고 믿습니다 . 차이점을 찾지 못하면 어댑터의 데이터 위치를 확인해야합니다.

이 컬렉션이 메모리에있는 경우을 호출하기 전에 실제로 항목을 삭제하거나 컬렉션에 추가했는지 확인하십시오 notifyDataSetChanged().

데이터베이스 또는 서비스 백엔드로 작업하는 경우을 호출하기 전에 메소드를 호출하여 정보를 다시 검색하거나 메모리 데이터를 조작해야합니다 notifyDataSetChanged().

문제는 notifyDataSetChanged데이터 세트가 변경된 경우에만 작동합니다. 따라서 변경 사항이없는 경우 살펴볼 곳입니다. 필요한 경우 디버그하십시오.

ArrayAdapter와 BaseAdapter

BaseAdapter와 같이 컬렉션을 관리 할 수있는 어댑터를 사용하면 더 잘 작동한다는 것을 알았습니다. ArrayAdapter와 같은 일부 어댑터는 이미 자체 컬렉션을 관리하므로 업데이트를위한 적절한 컬렉션에 도달하기가 더 어렵습니다. 그것은 실제로 대부분의 경우 불필요하게 여분의 어려움 층입니다.

UI 스레드

UI 스레드에서 호출해야합니다. 다른 답변에는이를 달성하는 방법에 대한 예가 있습니다. 그러나이 정보는 UI 스레드 외부에서 작업하는 경우에만 필요합니다. 그것은 서비스 또는 비 UI 스레드에서 온 것입니다. 간단한 경우에는 버튼 클릭이나 다른 활동 / 조각으로 데이터를 업데이트합니다. 여전히 UI 스레드 내에 있습니다. 항상 runOnUiTrhead를 팝업 할 필요가 없습니다.

빠른 예제 프로젝트

https://github.com/hanscappelle/so-2250770.git 에서 찾을 수 있습니다 . Android Studio (gradle)에서 프로젝트를 복제하고 엽니 다. 이 프로젝트에는 ListView모든 임의의 데이터 가 포함 된 MainAcitivity 빌딩이 있습니다. 이 메뉴는 작업 메뉴를 사용하여 새로 고칠 수 있습니다.

이 예제 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


16
네가 틀렸어. notifyDataSetChanged ()는 저에게 효과적이지 않지만 invalidateViews ()는 올바르게 작동했습니다.
babay

6
목록의 실제 요소가 변경되지 않는 문제가 있습니다 (예 : 동일한 양의 요소). 그러나 문제는 그들이 제시되는 방식이 변화되어야한다는 것입니다. 즉, UI를 빌드하기위한 어댑터 코드를 다시 실행 한 다음 목록 행에서 일부 요소를 올바르게 숨겨야합니다. notifyDataSetChanged ()가 작동하지 않습니다 ...
Sven Haiges

9
이 답변은 정말 도움이되었습니다. 특정 기능상의 이유로 배열을 메모리에 유지했습니다. 문제를 해결하기 위해 지금 전화 adapter.clear()하고 adapter.addAll(Array<T>)전화하기 전에notifyDataSetChanged()
Michael DePhillips

2
@hcpl, CheckBox에 대한 어댑터의 OnClickListener에 있으면 notifyDataSetChanged를 어떻게 호출해야합니까? invalidateViews가 지금 작업을 완료하고 있습니다. invalidateViews가 잘못된 호출 방법을 보는 이유는 무엇입니까?
크레인

1
notifyDataSetChanged가 작동하지 못했습니다. 어댑터에 공급 한 컬렉션이 변경되었지만 (요소가 제거됨) notifyDataSetChanged가 아무 작업도 수행하지 않았 음을 분명히 알 수있었습니다. 이 방법이 잘못되었는지 확실하지 않습니까?
byemute

42

원할 때마다 실행 가능 전화 :

runOnUiThread(run);

OnCreate()실행 가능한 스레드를 설정합니다.

run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};

1
TCP 연결 ( "nonUI"스레드)에서 오는 데이터를 기반으로 목록보기를 업데이트해야하는 경우에도 작동합니다. 목록을 다시 그리려면 ArrayList의 모든 요소를 ​​지우고 다시 추가해야합니다. 어쨌든 이미 UI 스레드에 있다면 runOnUiThread()함수 를 통해 코드를 호출 할 필요가 없습니다 .
Andre

감사! 그것은 나를 위해 작동합니다. 조각에서이 작업을 실행하려는 모든 사람들을 위해, 당신은 getActivity ()를 사용한다 runOnUiThread (새의 Runnable을 ... 확인 코드가 UI 스레드에서 실행되어 있는지 확인 할 수 있습니다.
codingpuss

나는 목적을 보지 못하고 run = new Runnable()내 함수에 public void refreshUIThread()메소드를 모델링 하는 메소드를 제공했다 run().
T.Woody

11

내 목록보기의 동적 새로 고침에 문제가 있습니다.

어댑터에서 notifyDataSetChanged ()를 호출하십시오.

notifyDataSetChanged ()를 호출하는 방법 / 언제에 대한 일부 추가 정보는이 Google I / O 비디오에서 볼 수 있습니다.

내 경우에는 notifyDataSetChanged ()가 제대로 작동하지 않았습니다 [다른 클래스에서 notifyDataSetChanged를 호출했습니다]. 이 경우 실행중인 활동 (스레드)에서 ListView를 편집했습니다. Christopher 덕분에 그 비디오 는 마지막 힌트를 주었다.

내 두 번째 수업에서 나는

Runnable run = new Runnable(){
     public void run(){
         contactsActivity.update();
     }
};
contactsActivity.runOnUiThread(run);

내 활동에서 update ()에 액세스합니다. 이 업데이트에는 다음이 포함됩니다

myAdapter.notifyDataSetChanged();

보기를 새로 고치도록 어댑터에 지시하십시오. 내가 말할 수있는 한 잘 작동했습니다.



5

여전히 ListView Refreshment에 만족하지 않으면이 스 니펫을 볼 수 있습니다.이 코드는 DB에서 listView를로드하기위한 것입니다. 실제로 CRUD 작업을 수행 한 후 ListView를 다시로드하는 것이 가장 좋습니다. 코드,하지만 원하는대로 ListView를 새로 고칩니다 ..

그것은 나를 위해 작동합니다 .... 더 나은 솔루션을 찾으면 공유하십시오 ...

.......
......
CRUD 작업을 수행하십시오 ..
......
.....
DBAdapter.open ();
DBAdapter.insert_into_SingleList ();
// DB_results를 가져 와서 내용으로 나열합니다.
                                            ls2.setAdapter (새로운 ArrayAdapter (DynTABSample.this,
    android.R.layout.simple_list_item_1, DBAdapter.DB_ListView));
                                            DBAdapter.close ();

2

이 게시물의 사람들이 제안한 솔루션은 주로 Android 버전의 기기에 따라 작동하거나 작동하지 않습니다. 예를 들어 AddAll 메서드를 사용하려면 android 장치에 android : minSdkVersion = "10"을 넣어야합니다.

모든 장치에 대해이 질문을 해결하기 위해 어댑터에서 자체 메소드를 작성하고 add 및 remove 메소드 내부에서 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!!!

1

새로 고칠 때 스크롤 위치를 유지하려면 다음을 수행하십시오.

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();
}

자세한 내용은 Android ListView : 새로 고칠 때 스크롤 위치 유지 를 참조하십시오 .


1

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();
        }
    });

1

부풀려있는 데이터를 가진 목록의 단일 객체를 사용해야합니다 ListView. 참조가 변경되면 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();
}
}

1
귀하의 설명은 과소 평가되었지만 실제로 배열 목록 참조에 대한 이해를 제공합니다. 감사합니다
Abraham Putra Prakasa

0

목록보기에서 데이터를 삭제 한 후을 호출해야합니다 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;

}

0

SimpleAdapter를 업데이트하는 데 notifyDataSetChanged ()를 사용할 수 없으므로 대신 removeAllViews ()를 사용하여 부모 레이아웃에 첨부 된 모든보기를 제거한 다음 ListView를 추가하고 작동하여 업데이트했습니다. 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);

0

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();

그것이 당신에게 의미가 있기를 바랍니다.


0

SimpleCursorAdapter를 사용하는 동안 어댑터에서 changeCursor (newCursor)를 호출 할 수 있습니다.


0

조각에서 한 번에 스캔 한 BLE 장치의 mac 주소로 ListView (단일 TextView로)를 채우고 싶을 때도 마찬가지였습니다.

내가 한 일은 다음과 같습니다.

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();
    }
}

그런 다음 ListView가 발견 된 장치의 mac 주소로 동적으로 채워지기 시작했습니다.


0

나는 그것이 새로 고침의 의미에 달려 있다고 생각합니다. GUI 표시를 화면 갱신해야합니까, 아니면 프로그램 적으로 getChildAt (int)를 호출하여 어댑터의 내용에 해당하는보기를 얻을 수 있도록 하위보기를 화면 갱신해야 함을 의미합니까?

GUI 표시를 새로 고치려면 어댑터에서 notifyDataSetChanged ()를 호출하십시오. 다음에 다시 그릴 때 GUI가 새로 고쳐집니다.

getChildAt (int)를 호출하고 어댑터에있는 내용을 반영하는보기를 얻으려면 layoutChildren ()을 호출하십시오. 그러면 어댑터 데이터에서 하위보기가 재구성됩니다.


0

목록보기에 표시하려는 ArrayList가 있습니다. ArrayList에는 mysql의 요소가 포함되어 있습니다. onRefresh 메서드를 재정의했으며 해당 메서드에서 tablelayout.removeAllViews ()를 사용 했습니다. 그런 다음 데이터베이스에서 데이터를 다시 가져 오는 프로세스를 반복했습니다. 그러나 그 전에 ArrayList 또는 데이터 structre 또는 새 데이터가 이전 데이터에 추가 될 것을 지우십시오.


0

서비스에서 UI 목록보기를 업데이트하려면 기본 활동에서 어댑터를 정적으로 설정하고 다음을 수행하십시오.

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

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

0

안드로이드 가이드 라인을 사용하고 ContentProviders있고 데이터를 가져 오기 Database위해를 ListView사용하고 CursorLoader있고를 사용하여 표시하는 경우 CursorAdapters관련 데이터에 대한 모든 변경 사항이 자동으로 ListView에 반영됩니다.

getContext().getContentResolver().notifyChange(uri, null);커서 ContentProvider는 변경 사항을 반영하기에 충분합니다. 추가 작업이 필요 없습니다.

그러나이 모든 것을 사용하지 않으면 데이터 세트가 변경 될 때 어댑터에 알려야합니다. 또한 데이터 세트 (예 : 목록)를 다시 채우거나 다시로드 한 다음 notifyDataSetChanged()어댑터 를 호출해야합니다 .

notifyDataSetChanged()datset에 변경 사항이 없으면 작동하지 않습니다. 다음은 문서의 메소드 위에 주석입니다.

/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */

0

새 어댑터 데이터를 가져온 다음 목록보기를 위해 어댑터를 재설정 한 다음과 같이 호출하여 notifyDataSetChanged 만 얻을 수있었습니다.

    expandableAdapter = baseFragmentParent.setupEXLVAdapter();
    baseFragmentParent.setAdapter(expandableAdapter);
    expandableAdapter.notifyDataSetChanged(); 

0

다른 옵션은 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
    }

0

어댑터로 목록을 전달했다고 가정하십시오.
사용하다:

list.getAdapter().notifyDataSetChanged()

목록을 업데이트하십시오.


0

여기에서 내 시나리오에 대해 이야기하면 삭제 버튼과 함께 db 값 목록을 표시하는 활동이 있고 삭제 버튼을 누르면 목록에서 해당 항목을 삭제하고 싶기 때문에 위의 답변이 작동하지 않습니다.

멋진 점은 리사이클 뷰를 사용하지 않고 간단한 목록보기와 해당 목록보기를 어댑터 클래스에서 초기화했다는 것입니다. 따라서를 호출하면 notifyDataSetChanged()어댑터 클래스 내부에서 delete 메소드가 어댑터 클래스에 있었기 때문에 어댑터 클래스가 초기화 된 활동 클래스에서도 아무 것도 수행하지 않습니다.

따라서 해결책은 어댑터 클래스 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()메소드는 Adapter 클래스에서 상속됩니다.

  • remove() -클릭 한 특정 항목을 제거
  • getItem(position) -클릭 한 위치에서 항목 (여기서 목록에 추가 한 Word 개체)을 가져 오는 것입니다.

이것은 활동 클래스에서 어댑터를 목록보기로 설정하는 방법입니다.

    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);

-1

가장 쉬운 방법은 새로운 Adaper를 만들고 기존 Adaper를 삭제하는 것입니다.

myListView.setAdapter(new MyListAdapter(...));

이것은 더 많은 메모리를 소비합니다.
Player 1

가비지가 수집됩니다
user1712200
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.