The use of RecyclerView

RecyclerView is a view control that includes linear layout, table layout and waterfall flow layout.




RecyclerView Inheritance relations.png


First customize Adapter by inheriting RecyclerView.Adapter. ViewHolder is mandatory in recyclerView. Adapter. To avoid some excessive memory usage.

public class MyAdapter extends RecyclerView.Adapter { private String[] mDataset; // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder public static class ViewHolder extends RecyclerView.ViewHolder { // each data item is just a string in this case public TextView mTextView; public ViewHolder(TextView v) { super(v); mTextView = v; } } // Provide a suitable constructor (depends on the kind of dataset) public MyAdapter(String[] myDataset) { mDataset =  myDataset; } // Create new views (invoked by the layout manager) @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup  parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false); // set the view's size, margins, paddings and layout parameters ... ViewHolder vh = new ViewHolder(v); return vh; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element holder.mTextView.setText(mDataset[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; }}Copy the code

In the Activity instantiation controller, you need to set the layout manager to select which layout to display:

public class MyActivity extends Activity { private RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_activity); mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); // use this setting to improve performance if you know that changes // in content do not change the layout size of the RecyclerView / / when you know your data changes will not change when the size of your layout Settings mRecyclerView. SetHasFixedSize (true); // use a linear layout manager mLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); // specify an adapter (see also next example) mAdapter = new MyAdapter(myDataset); mRecyclerView.setAdapter(mAdapter); }... }Copy the code

Set the above two parameters can realize RecyclerView

addItem && removeItem

Adding and removing items in RecyclerView is easy to implement. Add the following methods to the Adapter:

/** * addItem * @param position * @param STR to add data */ public void addItem(int position, String str){ list.add(position, str); notifyItemInserted(position); } public void removeItem(int position){list.remove(position);} public void removeItem(int position){list.remove(position); notifyItemRemoved(position); // This line animates the removal of item}Copy the code

Add headerView and footerView:

By overwriting the getItemViewType method in Adapter, position=0 and position=getItemCount()-1 return a different value in the

@override public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Header /footer return new RecyclerViewHoler(root); }Copy the code

Each method overridden in Adapter has to do something unique to view and position. Because header/footer is already added. The data is populated from the second to the inverse of 1. The following is the source code translation.

/** 
  * Return the view type of the item at positionFor the purposes of view recycling. * Returns the view type of the position item used for view recycling * *

The default implementation of this method returns 0, making the assumption of * a single view type for the adapter. Unlike ListView adapters, Types need not * be contiguous. Consider using ID resources to Counting identify item view types. A single view does not need to be contiguous like the Adapter in the ListView. * * @param position position to query * @return INTEGER value identifies the type of the view needed to represent the item at * position. Type codes need not be contiguous. */ public int getItemViewType(int position) { return 0; }

Copy the code

One problem with the above method is that only one item of the GridView is occupied when converted to a GridLayoutManger. Not a whole line. So we set the setSpanSizeLookup listener, which is used to get how many squares each position occupies. We just need to return 3 at the end of position == 0 and position == getItemCount() -1. (This value is determined by how many columns you set to each row.) The third item is the size of 1 item:

GridLayoutManager manager = new GridLayoutManager(this, 3); manager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return (3 - position % 3); }});Copy the code

Waterfall flow implementation:

Dynamically resize the controls in the holder in OnBindViewHolder using StaggerdGridManager

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.iV.getLayoutParams(); params.height = randomHight(); / / the effect of the random height constitutes the waterfall flow holder. IV. SetLayoutParams (params);Copy the code

Add a dividing line

The principle of adding a line is to draw a line under each Item. Through inheritance RecyclerView. ItemDecoration customize the style of the line, and then rewrite setItemOffset methods to set the offset. The offset of each item is set according to the vertical/height/width of the layout.

/ * * * draw vertical line (with RecyclerView content in size to draw the line) * mDrivider is obtaining the system default android state Richard armitage TTR event. The drawable listDivider * * @ @ param c canvas param Public void drawVertical(Canvas C, RecyclerView parent) {final int left = parent.getPaddingLeft(); Final int right = parent.getwidth () -parent.getPaddingright (); Final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; / / at the top of the starting point coordinates final int bottom. = top + mDivider getIntrinsicHeight (); // mDivider. SetBounds (left, top, right, bottom); mDivider.draw(c); }}Copy the code

The above method is called in the onDraw() method. Call setItemOffset() to set the offset:

@Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); }}Copy the code

Summary: More native than the previous ListView, GridView, etc., although more complex to write, but also means that you can do more customization. More changes can be made depending on the business. Is amazing. Charming. There's so much to learn!

  • On the assumption that Imagine; A; take
  • We have a contiguous number of people. The nearby; Contact with the
  • A no information is needed. uniquely