2011-02-04 4 views
38

ListViewBaseAdapter의 확장자를 사용하고있어 제대로 새로 고칠 수 없습니다. 새로 고침하면 스크롤 이벤트가 발생할 때까지 이전 데이터가 새 데이터 위에 그려집니다. 이전 행은 새 행 위에 그으나 스크롤을 시작하면 이전 행이 사라집니다.Android : ListView 내용을 새로 고치는 방법?

invalidateViews(), notifyDataSetChanged()notifyDataSetInvalidated()을 호출 해 보았습니다. 내 코드는 다음과 같습니다.

+0

혹시이 질문에 대한 답을 찾으셨습니까 다른 합병증이나 성능 문제의 원인은? 나는 똑같은 문제를 겪고있다. – CjS

+0

나도 같은 문제가있어, 누구든지 해결 했니? – dexxtr

+0

어느 하나의 plse는 기존 데이터 onscrolllistener로 새 listdata를 업데이트하는 방법을 도와줍니다 – Harsha

답변

60

, 나는 이런 식으로 해결 처음에는 나에게 명확하지 않았기 때문에 이것을 지적하고자했습니다. notifyDataSetChanged()을 호출하지 않으면보기가 업데이트되지 않습니다. 아래의 코드에 의해

+1

많은 도움이되었습니다. 내 문제는 그 대신에'ListArrayAdapter.clear();'라는 새로운 빈 ListAdapter를 다시 만들고 있었기 때문에 다른 솔루션들도 작동하지 않았다. – TheBronx

+3

그'dbh'는 무엇입니까? – akhyar

+0

dbh는 데이터베이스 핸들러의 인스턴스입니다. @akhyar – Odin

2

invalidateViews()를 사용하면 똑같은 일을하고 저에게는 효과가 있습니다. 즉시 무효화하려면 invalidateViews를 호출 한 후 postInvalidate를 호출 해 볼 수 있습니다.

+0

고마워, 나는 성공하지 않고 이것을 시도했다. 다른 제안? – ab11

11

ListView의 내용을 업데이트하기 위해 새 어댑터를 만들 필요는 없습니다. 단순히 필드에 어댑터를 저장하고 다음 코드를 사용하여 목록을 업데이트 :

mAdapter.setList(yourNewList); 
mAdapter.notifyDataSetChanged(); 

는 것을 명확히하기 위해, 당신의 활동은 같아야합니다 :

private YourAdapter mAdapter; 

protected void onCreate(...) { 

    ... 

    mAdapter = new YourAdapter(this); 
    setListAdapter(mAdapter); 

    updateData(); 
} 

private void updateData() { 
    List<Data> newData = getYourNewData(); 
    mAdapter.setList(yourNewList); 
    mAdapter.notifyDataSetChanged(); 
} 
+0

고마워, 나는 성공하지 않고 이것을 시도했다. 다른 제안? – ab11

+1

이 코드가 작동해야합니다. 어댑터와 setList() 메소드를 설정하는 부분을 게시 할 수 있습니까? – Gubbel

+0

그래서 ListActivity를 전체 화면 (style/Theme.NoBackground)으로 설정하면 설명 된 문제가 발생합니다. 하지만 Dialog 테마로 설정하면 제대로 새로 고칩니다. – ab11

3

을 나는 너무 시도 무효화 (), invalidateViews(), notifyDataSetChanged(). 그들은 모두 특정 상황에서 작동 할 수도 있지만 제 경우에는 그 일을하지 않았습니다.

필자의 경우 목록에 새로운 행을 추가해야만 제대로 작동하지 않습니다. 새 어댑터를 만들면 문제가 해결됩니다.

디버깅하는 동안 데이터가 있지만 렌더링되지 않은 것을 알았습니다. invalidate() 또는 invalidateViews()가 렌더링되지 않으면 (내가 예상 한대로), 나는 무엇을 할 것인지 모른다.

수정 된 데이터를 새로 고치기 위해 새 어댑터 개체를 만드는 것은 좋지 않은 것처럼 보입니다. 확실히 작동합니다. 유일한 단점은 어댑터에 새 메모리를 할당하는 데 소모되는 시간 일 수 있지만 Android 시스템이 충분히 똑똑하고 효율적으로 유지할 수 있다고 가정하면 정상적인 상태 여야합니다.

방정식에서 벗어나는 경우 흐름은 notifyDataSetChanged를 호출 할 때와 거의 같습니다. 같은 의미의 어댑터 함수 집합이 두 경우 모두 호출됩니다.

그래서 우리는 많이 잃지 않고 많이 얻고 있습니다.

+1

목록보기의 배경색을 설정하면 새로 고침 문제가 많이 사라졌습니다. – ab11

3

다른 데이터로 동일한 어댑터를 채우는 것이 더 좋거나 더 나은 기술이라고 생각합니다. 오른쪽 인자 u는 업데이트 된 목록 (내 경우에는 이름)

public void refill(ArrayList<BeanDatabase> names) { 
    list.clear(); 
    list.addAll(names); 
    list.notifyDataSetChanged(); 
} 
와 목록의 데이터를 업데이트 콜이 (내 경우 이름으로 표시 할 데이터 목록)와 어댑터 클래스에서이 메소드를 넣어

목록을 업데이트 할 때 어댑터를 변경하거나 어댑터를 몇 번이나 다시 설정하면 강제 종료 오류로 인해 어느 시점에서 문제가 발생할 수 있습니다. (오류 : 목록 데이터가 업데이트되었지만 어댑터가 목록보기에 알림을 표시하지 않습니다.)

11

데이터가 변경 될 때 즉시 ListView를 새로 고치려면 RunOnUiThread()notifyDataSetChanged()을 호출해야합니다.다음,

List<Item> newItems = databaseHandler.getItems(); 
ListArrayAdapter.clear(); 
ListArrayAdapter.addAll(newItems); 
ListArrayAdapter.notifyDataSetChanged(); 
databaseHandler.close(); 

내가 먼저 어댑터에서 데이터를 삭제 항목의 새 컬렉션을 추가, 만 다음 notifyDataSetChanged(); 이 설정 : 그 여전히 가지고 문제

private void updateData() { 
    List<Data> newData = getYourNewData(); 
    mAdapter.setList(yourNewList); 

    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
       mAdapter.notifyDataSetChanged(); 
     } 
    }); 
} 
+1

나는 2 시간 동안 StackOverflow를 빗질 해왔고, 도움이되지 않는 "call notifyDataSetChanged"조언과 같은 것을 발견했다. 귀하의 답변은 실제로 작동합니다. 감사! – Nevermind

+0

mAdapter가 최종해야한다고 말하고 있습니까? –

+0

@FarazAhmad mAdapter가 로컬 변수 인 경우 final이어야하지만 mAdapter가 (Activity) 변수의 인스턴스 인 경우에는 반드시 필요하지는 않습니다 :) – Aigori

1

업데이트의 ListView의 내용을 :

private ListView listViewBuddy; 
private BuddyAdapter mBuddyAdapter; 
private ArrayList<BuddyModel> buddyList = new ArrayList<BuddyModel>(); 

에서 onCreate() :

listViewBuddy = (ListView)findViewById(R.id.listViewBuddy); 
mBuddyAdapter = new BuddyAdapter(); 
listViewBuddy.setAdapter(mBuddyAdapter); 

onDataGet (웹 서비스 호출 후 또는 로컬 데이터베이스 또는 otherelse) :

mBuddyAdapter.setData(buddyList); 
mBuddyAdapter.notifyDataSetChanged(); 

BaseAdapter :

private class BuddyAdapter extends BaseAdapter { 

    private ArrayList<BuddyModel> mArrayList = new ArrayList<BuddyModel>(); 
    private LayoutInflater mLayoutInflater= (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    private ViewHolder holder; 

    public void setData(ArrayList<BuddyModel> list){ 
     mArrayList = list; 
    } 

    @Override 
    public int getCount() { 
     return mArrayList.size(); 
    } 

    @Override 
    public BuddyModel getItem(int position) { 
     return mArrayList.get(position); 
    } 

    @Override 
    public long getItemId(int pos) { 
     return pos; 
    } 

    private class ViewHolder { 
     private TextView txtBuddyName, txtBuddyBadge; 

    } 
    @SuppressLint("InflateParams") 
    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      holder = new ViewHolder(); 
      convertView = mLayoutInflater.inflate(R.layout.row_buddy, null); 
      // bind views 
      holder.txtBuddyName = (TextView) convertView.findViewById(R.id.txtBuddyName); 
      holder.txtBuddyBadge = (TextView) convertView.findViewById(R.id.txtBuddyBadge); 

      // set tag 
      convertView.setTag(holder); 
     } else { 
      // get tag 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.txtBuddyName.setText(mArrayList.get(position).getFriendId()); 

     int badge = mArrayList.get(position).getCount(); 
     if(badge!=0){ 
      holder.txtBuddyBadge.setVisibility(View.VISIBLE); 
      holder.txtBuddyBadge.setText(""+badge); 
     }else{ 
      holder.txtBuddyBadge.setVisibility(View.GONE); 
     } 

     return convertView; 
    } 
} 

당신이 업데이트 목록보기 원하는 두 줄의 코드를 아래에 전화 할 때마다 :

mBuddyAdapter.setData(Your_Updated_ArrayList); 
mBuddyAdapter.notifyDataSetChanged(); 

1

완료 만이 나를 위해 작동 매번, 내가 그것을 모른다면 나는주의해야한다.

private void updateListView(){ 
     listview.setAdapter(adapter); 
    } 
0

또 다른 쉬운 방법 :

//In your ListViewActivity: 
public void refreshListView() { 
    listAdapter = new ListAdapter(this); 
    setListAdapter(listAdapter); 
} 
관련 문제