2015-10-07 76 views
1

我有一個RecyclerView,我用它來顯示從使用LoaderManager內容提供商獲取的數據。它工作正常,但我發現我當大數據加載下面執行一些性能問題,有一個在爲我使用的是ViewPager加載承載這種方法與數據RecyclerView從LoaderManager

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Favorites = new ArrayList<>(); 

    if (cursor != null) { 
     while (cursor.moveToNext()) 
      Favorites.add(FavoritesModel.fromCursor(cursor)); 
    } 
    adapter = new FavoritesAdapter(getActivity(),Favorites); 
    favoritesRecyclerView.setAdapter(adapter); 
    } 

所以Fragment顯示的數據滯後我選擇要做到以下幾點:

@Override 
public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    ........ 
    adapter = new FavoritesAdapter(getActivity(),Favorites); 
    favoritesRecyclerView.setAdapter(adapter); 
    ........ 

,然後在onLoadFinished

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Favorites = new ArrayList<>(); 

    if (cursor != null) { 
     while (cursor.moveToNext()) 
      Favorites.add(FavoritesModel.fromCursor(cursor)); 
    } 
    adapter.notifyDataSetChanged(); 

    } 

使用這種沒有東西顯示出來。什麼是自onLoadFinished問題總是打來電話,我知道它一直被稱爲UI線程

+0

好吧@Blackbelt回答爲什麼你不得不空列表...現在有關滯後...它很簡單... **第一種解決方案:(優先)不使用模型**(作爲迭代光標和創建模型對象創建滯後)...直接在適配器中使用光標(谷歌的如何連接光標和RecyclerView的適配器).... **第二種解決方案是** ...在主線程之外移動當前的'onLoadFinished'代碼... – Selvin

+0

這是我想到的不過RecyclerView的適配器實現過濾,允許搜索小工具進行搜索,使用適配器光標將有可能做到這一點 –

+0

嗯過濾用裝載機是很容易的使用'restartLoader' – Selvin

回答

0

那是因爲這裏

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Favorites = new ArrayList<>(); 

你要麼重寫的Favorites舊引用或你中率先通過空地點。如果您在提交適配器之前初始化了Favorites,則刪除Favorites = new ArrayList<>();應修復空列表問題。

+0

我不是初始化收藏其他任何地方,除了當onLoadFinished被調用。這樣做會導致數據的多個副本存在 –

+0

我得到了這個答案百感交集...... *這是因爲這裏的* ...**「it」**在這個答案中沒有很好的定義,因爲實際上有兩個問題......所以這個答案回答了關於空列表的問題......而不是關於滯後 – Selvin

+0

@Selvin帶*這裏* ,我的意思是在片段中。我肯定錯過了*滯後*部分 – Blackbelt

6

我希望你有正確的答案。那麼我有同樣的問題,並做了一些很好的搜索,並最終提出了這一點。

這是適配器

public class RecordAdapter extends RecyclerView.Adapter<RecordAdapter.ViewHolder> { 
    Cursor dataCursor; 
    Context context; 

    public static class ViewHolder extends RecyclerView.ViewHolder { 
     public TextView time; 
     public TextView date; 
     public TextView distance; 
     public ImageView imageView; 
     public ViewHolder(View v) { 
      super(v); 
      time = (TextView) v.findViewById(R.id.time); 
      date = (TextView) v.findViewById(R.id.date); 
      distance = (TextView) v.findViewById(R.id.distance); 
      imageView = (ImageView) v.findViewById(R.id.image); 
     } 
    } 

    public RecordAdapter(Activity mContext, Cursor cursor) { 
     dataCursor = cursor; 
     context = mContext; 
    } 

    @Override 
    public RecordAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View cardview = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.record_row, parent, false); 
     return new ViewHolder(cardview); 
    } 

    public Cursor swapCursor(Cursor cursor) { 
     if (dataCursor == cursor) { 
      return null; 
     } 
     Cursor oldCursor = dataCursor; 
     this.dataCursor = cursor; 
     if (cursor != null) { 
      this.notifyDataSetChanged(); 
     } 
     return oldCursor; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     dataCursor.moveToPosition(position); 

     String time = dataCursor.getString(dataCursor.getColumnIndex(FitContract.RecordData.TIME)); 
     String date = dataCursor.getString(dataCursor.getColumnIndex(FitContract.RecordData.DATE)); 
     String distance = dataCursor.getString(dataCursor.getColumnIndex(FitContract.RecordData.DISTANCE)); 

     holder.time.setText(time); 
     holder.date.setText(date); 
     holder.distance.setText(distance); 
    } 

    @Override 
    public int getItemCount() { 
     return (dataCursor == null) ? 0 : dataCursor.getCount(); 
    } 
} 

那麼這樣的片段(您可以使用活動以及)

public class RecordFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { 
    private RecyclerView recyclerView; 
    RecordAdapter adapter; 
    private int LOADER_ID = 1; 

    @Override 
    public View onCreateView(LayoutInflater inflater, 
          @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.record_layout, container, false); 

     recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view_record); 
     recyclerView.setHasFixedSize(true); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 

     FloatingActionButton fab = (FloatingActionButton) rootView.findViewById(R.id.fab_record); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Log.d("RECORD_FRAGMENT", "FAB"); 
       startActivity(new Intent(getContext(), LineChartActivity.class)); 
      } 
     }); 

     adapter = new RecordAdapter(getActivity(), null); 
     recyclerView.setAdapter(adapter); 
     return rootView; 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     getLoaderManager().initLoader(LOADER_ID, null, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     return new CursorLoader(getContext(), FitContract.RecordData.CONTENT_URI, null, null, null, null); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     adapter.swapCursor(data); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     adapter.swapCursor(null); 
    } 
}