RecyclerView actual use
Make a list using RecyclerView. Display test data.
This example is broken down into the following steps:
- Determine the data. We’re using analog data here.
- Design the UI and presentation.
- Write layouts and adapters.
Simulated data
You can’t make bricks without straw. Simulated data is simulated demand.
Create a new class, DataTest, and design four properties.
public class DataTest {
private String timezone;
private int number;
private int personCount;
private int count;
public DataTest(String timezone, int number, int personCount, int count) {
this.timezone = timezone;
this.number = number;
this.personCount = personCount;
this.count = count;
}
// getter setter...
}
Copy the code
Design the layout of items
Design the UI to display four property values in a single line. Item uses item_recy2.xml
<? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/tv1" style="@style/RePage2Header" android:layout_marginEnd="@dimen/re_2_half_gap" /> <TextView android:id="@+id/tv2" style="@style/RePage2Header" android:layout_marginStart="@dimen/re_2_half_gap" android:layout_marginEnd="@dimen/re_2_half_gap" /> <TextView android:id="@+id/tv3" style="@style/RePage2Header" android:layout_marginStart="@dimen/re_2_half_gap" android:layout_marginEnd="@dimen/re_2_half_gap" /> <TextView android:id="@+id/tv4" style="@style/RePage2Header" android:layout_marginStart="@dimen/re_2_half_gap" /> </LinearLayout>Copy the code
Prepare resources such as colors, sizes, etc
The relevant style and color, size profile is in the res/values directory.
The style file style.xml.
<style name="RePage2Header"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">40dp</item> <item name="android:layout_weight">2</item> <item name="android:textColor">#ffffff</item> <item name="android:gravity">center</item> <item name="android:background">@color/rePage2Item</item> </style>Copy the code
We set layout_width to 0dp for each TextView in layout. To use the layout_weight attribute. Let their four TextViews split the width of their parent View proportionally.
The segmentation here uses the segmentation ratio of the LinearLayout.
In the color configuration file color.xml, add the following color Settings.
<color name="rePage2Item">#082941</color>
Copy the code
Size configuration dimens.xml.
<dimen name="re_2_gap">4dp</dimen>
<dimen name="re_2_half_gap">2dp</dimen>
Copy the code
Design ViewHolder
With the resource file and layout ready, start writing the corresponding viewHolder. Here we also put the VH class and Adapter class inside the Activity class.
private class VH extends RecyclerView.ViewHolder { TextView tv1; TextView tv2; TextView tv3; TextView tv4; public VH(@NonNull View itemView) { super(itemView); tv1 = itemView.findViewById(R.id.tv1); tv2 = itemView.findViewById(R.id.tv2); tv3 = itemView.findViewById(R.id.tv3); tv4 = itemView.findViewById(R.id.tv4); }}Copy the code
Design Adapter classes
Adapter Adapter class.
private class Adapter extends RecyclerView.Adapter<VH> { private List<DataTest> dataList = new ArrayList<>(); public Adapter() { } public void setDataList(List<DataTest> dataList) { this.dataList = dataList; // notifyDataSetChanged() is better; } @NonNull @Override public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new VH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recy2, parent, false)); } @Override public void onBindViewHolder(@NonNull VH holder, int position) { DataTest dataTest = dataList.get(position); holder.tv1.setText(dataTest.getTimezone()); holder.tv2.setText(String.valueOf(dataTest.getNumber())); holder.tv3.setText(String.valueOf(dataTest.getPersonCount())); holder.tv4.setText(String.valueOf(dataTest.getCount())); } @Override public int getItemCount() { return dataList.size(); }}Copy the code
Configuration RecyclerView
Set the recyclerview.
Private Adapter mAdapter = new Adapter(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_recy_2); RecyclerView recyclerView = findViewById(R.id.re_view); recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false)); recyclerView.setAdapter(mAdapter); mAdapter.setDataList(genDataTestList()); recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.top = getResources().getDimensionPixelOffset(R.dimen.re_2_gap); }}); Private List<DataTest> genDataTestList() {List<DataTest> List = new ArrayList<>(); for (int i = 1; i <= 60; I ++) {DataTest d = new DataTest(" time zone "+ I, I, I, I); list.add(d); } return list; }Copy the code
Configure recyclerView in the onCreate method. RecyclerView addItemDecoration method is to give the item set intervals. GetItemOffsets Sets the spacing of subitems. This gives the bottom of the subitem a spacing value. The specific value is set in DImen. GenDataTestList () is the data that generates the simulation.
Use include to modify layout
Some friends ask: table header and item structure is the same, can reuse?
Well, you can. We can use the include tag in a Layout to “include” another Layout file. Copy act_recy_2. XML and paste it to get act_recy_2_include. XML. Change the LinearLayout from the original table header to include.
<include layout="@layout/item_recy2" />
Copy the code
Create a layout for include, which is the item_recy2 layout we defined for the item. When we want to add a margin-top, like this
<include
android:layout_marginTop="4dp"
layout="@layout/item_recy2" />
Copy the code
As will pop up a warning:
Layout parameter layout_marginTop ignored unless both layout_width and layout_height are also specified on tag
In the include tag, if you want to set other attributes, you need to set layout_width and layout_height first.
I’m going to change it, and I’m going to add an ID, so it looks like this.
<include
android:id="@+id/header"
layout="@layout/item_recy2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp" />
Copy the code
Let the Activity use this layout. Modify RecyclerViewDemo2Act.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_recy_2_include); initHeader(); Private void initHeader() {View header = findViewById(r.id.ader); TextView tv1 = header.findViewById(R.id.tv1); Tv1. SetText (" time zone "); TextView tv2 = header.findViewById(R.id.tv2); Tv2. SetText (" serial number "); TextView tv3 = header.findViewById(R.id.tv3); Tv3. SetText (" personnel "); TextView tv4 = header.findViewById(R.id.tv4); Tv4. SetText (" number "); }Copy the code
We added a method initHeader(). So I’m going to find the header, and I’m going to use the header to find its child views, which are the four TextViews. Set the text separately.
RecyclerView
1. Will pre-layout occur when RecyclerView is used for the first time?
Pre-layout is not triggered for the first time. Pre-layout will only be triggered each time notify change. The purpose is to record the coordinates of ViewHolder at each position on the screen by saveOldPosition method. After relayout, the animation effect of Item will be realized by comparison.
2. When is ViewHolder cached in RecycledViewPool?
There are mainly the following two situations:
- When the ItemView is swiped off screen and CachedView is full, the ViewHolder is cached into the RecycledViewPool
- When data changes, ViewHolder after disappearRance will be cached in RecycledViewPool
3. The relationship between CachedView and RecycledViewPool
When an ItemView is swiped off the screen, it is saved in CachedView by default. CachedView has a default size of 2 and can be changed using the setItemViewCacheSize method.
When CachedView is full and a new ItemView slips out of the screen, it will force CachedView to transfer the ViewHolder of the cache to RecycledViewPool according to FIFO rules.
The default size of RecycledViewPool is 5. You can modify the cache size of RecycledViewPool in the following ways:
RecyclerView.getRecycledViewPool().setMaxRecycledViews(int viewType, int max);
Copy the code
4. Difference between CachedView and RecycledViewPool
The ViewHolder cached in the CachedView does not clean up relevant information (such as position, state, etc.), so a ViewHolder that has just been removed from the screen can be retrieved and displayed in the CachedView when it is moved back to the screen. No rebinding (bindViewHolder) is required.
And the ViewHolder cached in RecycledViewPool will be cleaned state and location information, so it is necessary to call bindViewHolder binding data again to find the ViewHolder from RecycledViewPool.
5. From what aspects did you optimize RecyclerView?
RecyclerView can be optimized from the following aspects:
- Try to put complex data processing operations into asynchrony. The data that RecyclerView needs to display is often obtained from the remote server request, but after the network request gets the data, the data needs to be flattened, and the best data format is returned to the UI thread as far as possible.
- Optimize the RecyclerView layout to avoid using it with ConstraintLayout
- For fast sliding events, you can use addOnScrollListener to add a listener for fast sliding to stop loading data when the user is fast sliding.
- If the ItemView has a fixed height, use setHasFixSize(true). In this way, RecyclerView can directly calculate the height in onMeasure stage, without the need to calculate the height of sub-ItemView for many times. This situation is very significant for vertical RecyclerView nested transverse RecyclerView.
- When UI is Tab feed stream, consider using RecycledViewPool to implement cache sharing of multiple RecyclerViews.
Android Zero Basics tutorial video reference