2014-10-29 5 views
34

RecyclerView에 대한 검색 기능을 구현하고 싶습니다. 텍스트가 변경되면이 위젯과 함께 표시되는 데이터를 변경하려고합니다. 어쩌면이 질문은 전에 질문이나 간단하지만있는 데이터를 표시 할 수있는 변화가 ...RecyclerView 데이터 세트 변경

내 RecyclerView과 같이 정의된다

은 다음 방법을 모르겠어요되었습니다

 // 1. get a reference to recyclerView 
    mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView); 

    // 2. set layoutManger 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    // 3. create an adapter 
    mAdapter = new ItemsAdapter(itemsData); 
    // 4. set adapter 
    mRecyclerView.setAdapter(mAdapter); 

그리고를 내가 어댑터를 다른 데이터 세트 (예를 들어 하나 개의 항목을 가지고있는) 다른 배열을 제공 할 때

ItemData itemsData[] = { new ItemData("Mary Richards"), 
     new ItemData("Tom Brown"), 
     new ItemData("Lucy London")   
}; 

그래서 내가 어떻게해야 할 때 : 나는 표시하고 데이터 뭔가처럼?

+0

방금 ​​그것으로 새로운'ItemsAdapter'을 만들 수있는 또 다른 배열을주고 싶어 다시'setAdapter' 호출하는 경우. –

답변

74

, 당신은 꽤 좋은 결과 (애니메이션)을 얻을 수있다 보기 소유자를 다시 사용하십시오. (대 setAdapter, 그것은 새로운 어댑터가 이전 어댑터와 동일한 ViewHolder 세트를 가지고 있다는 것을 모르기 때문에 모든 뷰를 재사용하고 다시 생성해야합니다).

더 나은 방법은 제거 할 항목을 찾고 notifyItemRemoved(index)을 호출하는 것입니다. 실제로 항목을 제거하는 것을 잊지 마십시오. 이렇게하면 RecyclerView에서 예측 애니메이션을 실행할 수 있습니다. 당신이 내부적으로 ArrayList를 사용하는 어댑터를 가정하면, 구현은 다음과 같습니다

// adapter code 
final List<ItemData> mItems = new ArrayList(); //contains your items 
public void filterOut(String filter) { 
    final int size = mItems.size(); 
    for(int i = size - 1; i>= 0; i--) { 
     if (mItems.get(i).test(filter) == false) { 
      mItems.remove(i); 
      notifyItemRemoved(i); 
     } 
    } 
} 

그것은 수행 할 것입니다 당신이 배치 notifyItemRemoved 통화를 할 수있는 대신 notifyItemRangeRemoved를 사용하는 경우 더 나은. 이 같은 STH 보일 것이다 : (테스트하지) 당신은 이전에 필터링 된 항목을 추가하려면이 코드를 확장해야

public void filterOut(String filter) { 
    final int size = mItems.size(); 
    int batchCount = 0; // continuous # of items that are being removed 
    for(int i = size - 1; i>= 0; i--) { 
     if (mItems.get(i).test(filter) == false) { 
      mItems.remove(i); 
      batchCount ++; 
     } else if (batchCount != 0) { // dispatch batch 
      notifyItemRangeRemoved(i + 1, batchCount); 
      batchCount = 0; 
     } 
    } 
    // notify for remaining 
    if (batchCount != 0) { // dispatch remaining 
     notifyItemRangeRemoved(0, batchCount); 
    } 
} 

을하지만 지금은 볼 수 있어야합니다 (예를 들어, 사용자가 필터 쿼리를 삭제)하지만 난이 사람이해야한다고 생각 기본 아이디어를 줘.

각 알림 항목 호출은 그 다음에 오는 항목 호출에 영향을 미친다는 점에 유의하십시오. 따라서 목록에서 피할 수 있도록 목록을 지나가고 있습니다. 끝에서 이동은 ArrayList의 메소드 제거 제거 (항목 이동 감소)에도 도움이됩니다.

예를 들어 처음부터 목록을 탐색하여 처음 두 항목을 제거한 경우입니다. 당신은

notifyItemRangeRemoved(0, 2); // 2 items starting from index 0 

또는 하나

notifyItemRemoved(0); 
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0 
+0

답변 해 주셔서 감사 드리며, 내 필요에 맞는 조정을하겠습니다. 그러나 이것이 기본적으로 필요한 것입니다. 너는 그것을 아주 잘 설명했다. – Sandra

+1

"안정적인 ID"는 무엇을 의미합니까? 내 데이터 집합이 변경되지만 어떤 방법으로 (일부 새 항목이 추가 될 수 있고 일부 항목이 제거 될 수 있음) 알지 못하지만보기가 동일하게 유지되므로 swapAdapter에 true 또는 false를 전달해야합니까? –

2

그냥 어댑터를 다시 초기화 :

mAdapter = 새로운 ItemsAdapter (newItemsData를);

또는 만이 아니라 전체 목록보다 몇 특정 항목을 추가, 제거해야하는 경우 :

mAdapter합니다. notifyItemInserted (위치);

또는

mAdapter.notiftyItemRemoved (위치); 당신이 당신의 어댑터를 안정적으로 ID를하는 경우 필터링 된 항목을 포함하는 새로운 배열을 생성하고 swapAdapter 힌트를 사용

recyclerView.swapAdapter(newAdapter, false); 

가 할 수있는 것을 RecyclerView 호출하는 경우

22

에 의해 그들에게 하나를 전달하는 경우에 내 대답은 전화해야 하나 - 자신의 사이트에서 이반 Skoric 덕분에 :

http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/ 나는 여분의 방법을 만들어 내 어댑터 클래스 내부 :

public void updateList(List<Data> data) { 
    mData = data; 
    notifyDataSetChanged(); 
} 

그런 다음 y 데이터가 변경되면이 메소드를 새 데이터를 전달하는 것으로 호출하면 뷰가 변경되어 뷰가 반영됩니다.

+0

notifyDataSetChanged()는 모든 애니메이션을 삭제하며 큰 목록에만 적합합니다. – Davidea

+0

@Davidea ... RecyclerView의 일반적인 사용 사례입니다. –

+0

recyclerview는 화면에서 스크롤 할 때 볼 수있는보기 만 메모리에 유지하고 해제합니다. 그것은 listview와 비교하여 메모리 관점에서 매우 효율적입니다. 이들은 listview와 유사하게 작동합니다. 여기에서 recyclerview 문서를 읽을 수 있습니다. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html – Simon

0

ygit으로 대답하면 전체 내용을 변경해야 할 때 swapAdapter이 재미 있습니다.

그러나 내 FlexibleAdapter에서 updateDataSet으로 항목을 업데이트 할 수 있습니다. notifyDataSetChanged을 호출하거나 동기화 애니메이션 (기본적으로 사용하도록 설정)을 사용하도록 어댑터를 구성 할 수도 있습니다. 즉, notifyDataSetChanged는 모든 애니메이션을 죽이기 때문에 큰 목록을 가지고있는 것이 좋습니다.

이 설명에서 참조하시기 바랍니다, demoApp 및 위키 페이지 : https://github.com/davideas/FlexibleAdapter