About RecyclerView
RecyclerView has been introduced since Android 5.0. ListView, which was often used before, inherited AbsListView, while RecyclerView directly inherits ViewGroup and implements ScrollingView and NestedScrollingChild interfaces. RecyclerView is a complete change compared to ListView.
RecyclerView is more advanced and flexible than listviews. For many views, it is a container that can be effectively reused and scrolled. Please use it when the data changes dynamically.
RecyclerView is very convenient to use because it provides:
1. It provides a layoutmanager for item positioning
2. Provide a default animations for item operations
3. You can also flexibly define the custom layout manager and animation of this widget
Implement pull-up refresh and pull-down refresh
Layout file:
<. xmlns:andro xmlns:tools="/tools" android: android:layout_width="match_parent" android:layout_height="match_parent" > <. android: android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="@null" android:scrollbars="vertical" /> </.>
Reference this layout in Activity and initialize it
@Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); mSwipeRefreshWidget = (SwipeRefreshLayout) findViewById(.swipe_refresh_widget); mRecyclerView = (RecyclerView) findViewById(); (.color1, .color2, .color3, .color4); (this); // This sentence is for displaying the loading progress bar when entering the page for the first time (false, 0, (int) TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources() .getDisplayMetrics())); (new () { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { (recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == ()) { (true); // In real projects, please change to the network request data code, sendRequest... (0, 3000); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { (recyclerView, dx, dy); lastVisibleItem = (); } }); (true); mLayoutManager = new LinearLayoutManager(this); (mLayoutManager); (new DefaultItemAnimator()); adapter = new SampleAdapter(); (adapter); // In real projects, please change to the network request data code, sendRequest... (0, 3000); }
Apis to note in SwipeRefreshLayout:
1. setOnRefreshListener(OnRefreshListener listener) Set pull-down monitoring, and when the user pulls down, the callback will be executed
2. setColorSchemeColors(int... colors) Set the color change of the progress bar, up to 4 colors can be set
3. setProgressViewOffset(boolean scale, int start, int end) Adjust the distance from the top of the screen
4. setRefreshing(boolean refreshing) Set whether SwipeRefreshLayout is currently in refresh state. It is generally set to true when requesting data, and set to false after the data is loaded into the View.
RecyclerView implementation:
The first type is to use the progress bar that comes with SwipeRefreshLayout when pull-down refresh and pull-up refresh
mRecyclerView = (RecyclerView) findViewById(); (new () { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { (recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == ()) { (true); // In real projects, please change to the network request data code, sendRequest... (0, 3000); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { (recyclerView, dx, dy); lastVisibleItem = (); } }); (true); mLayoutManager = new LinearLayoutManager(this); (mLayoutManager); (new DefaultItemAnimator()); adapter = new SampleAdapter(); (adapter);
The second way to implement pull-down refresh is to use the progress bar that comes with SwipeRefreshLayout, and pull-up refresh is to use a refresh similar to ListView to prompt "Loading" and other information.
We can also add an item similar to FooterView to the RecyclerView.
We implement it in Adapter:
public class SampleAdapter extends <ViewHolder> { private List<Integer> list; private static final int TYPE_ITEM = 0; private static final int TYPE_FOOTER = 1; public List<Integer> getList() { return list; } public SampleAdapter() { list = new ArrayList<Integer>(); } // The count of RecyclerView is set to the total number of data digits + 1 (footerView) @Override public int getItemCount() { return () + 1; } @Override public int getItemViewType(int position) { // The last item is set to footerView if (position + 1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } @Override public void onBindViewHolder(ViewHolder holder, final int position) { if (holder instanceof ItemViewHolder) { ((ItemViewHolder) holder).((list .get(position))); } } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_ITEM) { View view = (()).inflate( .list_item_text, null); (new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); return new ItemViewHolder(view); } // type == TYPE_FOOTER Return footerView else if (viewType == TYPE_FOOTER) { View view = (()).inflate( , null); (new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); return new FooterViewHolder(view); } return null; } class FooterViewHolder extends ViewHolder { public FooterViewHolder(View view) { super(view); } } class ItemViewHolder extends ViewHolder { TextView textView; public ItemViewHolder(View view) { super(view); textView = (TextView) (); } } }
In this way, we can do some processing for the footerview layout, such as prompting "Loading," and "already loaded". More flexible