RecyclerView 设置布局格式
1 2 3 4 5
| mRecyclerView = (RecyclerView) v.findViewById(R.id.main_rv);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
|
RecyclerView 添加适配器 以及设置item点击监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| MainFragment.java
mRecyclerViewAdapter = new RecyclerViewAdapter(getActivity(), mItems, false); mRecyclerView.setAdapter(mRecyclerViewAdapter)
mRecyclerViewAdapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListenerCustom() { @Override public void onItemClick(String id, String title) { Log.i(LogKeys.MAIN_FRAGMENT, "item is clicked "); Intent intent = new Intent(getActivity(), MovieDetailActivity.class); intent.putExtra(TransferKeys.MAIN_MOVIE_DETAIL_ID, id); intent.putExtra(TransferKeys.MAIN_MOVIE_DETAIL_MOVIE_NAME, title); startActivity(intent); Log.i(LogKeys.MAIN_FRAGMENT, "startactivity"); } });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private final Context mContext; private List<MainItem> mData; private OnItemClickListenerCustom mCallback; private boolean mIsComingMovie; private int mTotalCount;
public interface OnItemClickListenerCustom { void onItemClick(String id,String title); }
public RecyclerViewAdapter_Main(Context context, List<MainItem> data, boolean isComingMovie) {
this.mContext = context; this.mData = data; this.mIsComingMovie=isComingMovie; }
public void refresh(ArrayList<MainItem> data){ mData.addAll(data); notifyDataSetChanged(); }
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view=LayoutInflater.from(mContext) .inflate(R.layout.item_movie_main,parent,false); return new ItemViewHolder(view); }
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((ItemViewHolder)holder).update(); }
@Override public int getItemCount() { return mData.size(); }
public void setOnItemClickListener(OnItemClickListenerCustom listener){ this.mCallback=listener; }
class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { TextView textTitle; MainItem mMainItem;
public ItemViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); }
public void update() { }
@Override public void onClick(View v) { if(mCallback!=null){ mCallback.onItemClick(mMainItem.getMovieId(),mMainItem.getTitle()); } } } }
|
RecyclerView上滑加载
要使FetchItemTask顺序执行, 否则当下滑触发loadMoreData时,会出现多个线程, 若这几个线程同时
进行,会导致数据重复加载, 这些Task顺序执行, 只需要在doInBackground执行时
检查star<mRecyclerViewAdapter.getStart()
若true, 则说明该线程为重复线程 return null
否则, 执行之后的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| MainFragmentBase.java mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { int lastVisibleItem; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == SCROLL_STATE_IDLE && lastVisibleItem + 1 >= mRecyclerViewAdapter.getItemCount() && mRecyclerViewAdapter.getItemCount() < mRecyclerViewAdapter.getTotalDataCount()) { loadMoreData(mRecyclerViewAdapter.getStart()); } }
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager(); lastVisibleItem = layoutManager.findLastVisibleItemPosition();
} });
protected abstract void loadMoreData(int start);
MainFragment.java extentds MainFragmentBase.java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);
new FetchItemTask(0).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); }
@Override protected void loadMoreData(int start) { new FetchItemTask(start).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); }
private class FetchItemTask extends AsyncTask<Void, Void, ArrayList<MainItem>> { private int start=0;
public FetchItemTask(int s){ start=s; }
@Override protected ArrayList<MainItem> doInBackground(Void... params) { if(start<mRecyclerViewAdapter.getStart()){ return null } DoubanFetchrMain df=new DoubanFetchrMain(0,start); mRecyclerViewAdapter.setTotalCount(df.getTotalCount()); return df.fetchItems_SubjectInTheaters(); }
@Override protected void onPostExecute(ArrayList<MainItem> galleryItems){ mItems = galleryItems; if(mItems==null){ return; } mRecyclerViewAdapter.addMoreData(mItems,start);
}
}
|
注意点
点击图片进入电影详细页面时, 如果在详细页面图片未加载时返回, 应用会crash.
应该是此时ImageView已经被销毁了, 所以就造成NullPointerException.
官方说已经解决这个问题, 但是下面这写法还是会crash.
1 2 3 4 5
| Glide.with(getActivity()) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .centerCrop() .into(imageMovie);
|
更改为
1 2 3 4 5 6 7 8 9 10
| onCreate(...){ mRequestManager=Glide.with(getActivity()); }
... mRequestManager .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .centerCrop() .into(imageMovie);
|
这样就不会出问题.