Android5.0新特性:RecyclerView实现上拉加载更多
RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势。下面这篇博客主要来实现RecyclerView的上拉加载更多功能。
基本思路是让RecyclerView的Adapter加载两种布局,第一个布局来显示主界面,第二个布局来显示上拉加载时的提示信息,让RecyclerView监听是否滑动到最后一个item,如果是,则调用上拉刷新的逻辑,拉取远程数据,并显示第二个布局。等加载完毕时,刷新
Adapter,并隐藏第二个布局。下面分析代码。
要加载两种不同的布局,Adapter要重写getItemViewType方法。
![](/assets/blank.gif)
@Overridepublic int getItemViewType(int position) {if (position == dataList.size())return 1;elsereturn 0;}
![](/assets/blank.gif)
onCreateViewHolder根据viewtype加载ViewHolder.
![](/assets/blank.gif)
@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view;if (viewType == 0) {view = LayoutInflater.from(context).inflate(R.layout.grid_redu_item, parent, false);return new NormalHolder(view);} else {view = LayoutInflater.from(context).inflate(R.layout.sample_common_list_footer, parent, false);mFooterHolder = new FooterHolder(view);return mFooterHolder;}}
![](/assets/blank.gif)
注意getItemCount长度要加1。
@Overridepublic int getItemCount() {return dataList.size() + 1;}
NormalHolder
![](/assets/blank.gif)
1 class NormalHolder extends RecyclerView.ViewHolder { 2 ImageView img; 3 TextView name; 4 5 public NormalHolder(View itemView) { 6 super(itemView); 7 img = (ImageView) itemView.findViewById(R.id.homepage_grid_picpic); 8 name = (TextView) itemView.findViewById(R.id.homepage_grid_name); 9 } 10 11 public void setData(int position) { 12 imageLoader.displayImage(context, imgUrls[position % imgUrls.length], img); 13 name.setText(dataList.get(position)); 14 } 15 }
![](/assets/blank.gif)
FooterHolder
![](/assets/blank.gif)
1 public class FooterHolder extends RecyclerView.ViewHolder { 2 View mLoadingViewstubstub; 3 View mEndViewstub; 4 View mNetworkErrorViewstub; 5 6 public FooterHolder(View itemView) { 7 super(itemView); 8 mLoadingViewstubstub = itemView.findViewById(R.id.loading_viewstub); 9 mEndViewstub = itemView.findViewById(R.id.end_viewstub); 10 mNetworkErrorViewstub = itemView.findViewById(R.id.network_error_viewstub); 11 } 12 13 //根据传过来的status控制哪个状态可见 14 public void setData(LoadingFooter.FooterState status) { 15 Log.d("TAG", "reduAdapter" + status + ""); 16 switch (status) { 17 case Normal: 18 setAllGone(); 19 break; 20 case Loading: 21 setAllGone(); 22 mLoadingViewstubstub.setVisibility(View.VISIBLE); 23 break; 24 case TheEnd: 25 setAllGone(); 26 mEndViewstub.setVisibility(View.VISIBLE); 27 break; 28 case NetWorkError: 29 setAllGone(); 30 mNetworkErrorViewstub.setVisibility(View.VISIBLE); 31 break; 32 default: 33 break; 34 } 35 36 } 37 38 //全部不可见 39 void setAllGone() { 40 if (mLoadingViewstubstub != null) { 41 mLoadingViewstubstub.setVisibility(View.GONE); 42 } 43 if (mEndViewstub != null) { 44 mEndViewstub.setVisibility(View.GONE); 45 } 46 if (mNetworkErrorViewstub != null) { 47 mNetworkErrorViewstub.setVisibility(View.GONE); 48 } 49 } 50 51 }
![](/assets/blank.gif)
FooterHolder布局:
![](/assets/blank.gif)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/loading_view"android:layout_width="match_parent"android:layout_height="40dp"android:gravity="center"android:orientation="vertical"tools:layout_height="wrap_content"><includeandroid:id="@+id/loading_viewstub"layout="@layout/sample_common_list_footer_loading"android:layout_width="match_parent"android:layout_height="40dp" /><includeandroid:id="@+id/end_viewstub"layout="@layout/sample_common_list_footer_end"android:layout_width="match_parent"android:layout_height="40dp" /><includeandroid:id="@+id/network_error_viewstub"layout="@layout/sample_common_list_footer_network_error"android:layout_width="match_parent"android:layout_height="40dp" /> </LinearLayout>
![](/assets/blank.gif)
显示效果:
主要逻辑放在Fragment里。 首先我们要绑定为RecyclerView绑定一个监听器,监听RecyclerView是否滑到了底部。 Listener代码:
![](/assets/blank.gif)
package com.yctime.truelove.LoadMore;import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View;import com.yctime.truelove.ImageLoader.UILPauseOnScrollListener;/*** Created by xjx* <p/>* 继承自RecyclerView.OnScrollListener,一:可以监听到是否滑动到页面最低部。二:滑动时停止加载图片*/ public class EndlessRecyclerOnScrollListener extends UILPauseOnScrollListener {/*** 当前RecyclerView类型*/protected LayoutManagerType layoutManagerType;/*** 最后一个的位置*/private int[] lastPositions;/*** 最后一个可见的item的位置*/private int lastVisibleItemPosition;/*** 当前滑动的状态*/private int currentScrollState = 0;@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();if (layoutManagerType == null) {if (layoutManager instanceof LinearLayoutManager) {layoutManagerType = LayoutManagerType.LinearLayout;} else if (layoutManager instanceof GridLayoutManager) {layoutManagerType = LayoutManagerType.GridLayout;} else if (layoutManager instanceof StaggeredGridLayoutManager) {layoutManagerType = LayoutManagerType.StaggeredGridLayout;} else {throw new RuntimeException("Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");}}switch (layoutManagerType) {case LinearLayout:lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();break;case GridLayout:lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();break;case StaggeredGridLayout:StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;if (lastPositions == null) {lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];}staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);lastVisibleItemPosition = findMax(lastPositions);break;}}@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);currentScrollState = newState;RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();int visibleItemCount = layoutManager.getChildCount();int totalItemCount = layoutManager.getItemCount();if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition) >= totalItemCount - 1)) {onLoadNextPage(recyclerView);}}/*** 取数组中最大值** @param lastPositions* @return*/private int findMax(int[] lastPositions) {int max = lastPositions[0];for (int value : lastPositions) {if (value > max) {max = value;}}return max;}public void onLoadNextPage(final View view) {}public static enum LayoutManagerType {LinearLayout,StaggeredGridLayout,GridLayout} }
![](/assets/blank.gif)
下面是Fragment完整代码:
![](/assets/blank.gif)
1 package com.yctime.truelove.fragment; 2 3 4 import android.support.v4.app.Fragment; 5 import android.support.v7.widget.DefaultItemAnimator; 6 import android.support.v7.widget.GridLayoutManager; 7 import android.support.v7.widget.LinearLayoutManager; 8 import android.support.v7.widget.RecyclerView; 9 import android.util.Log; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 13 import com.yctime.truelove.LoadMore.EndlessRecyclerOnScrollListener; 14 import com.yctime.truelove.LoadMore.LoadingFooter; 15 import com.yctime.truelove.MainActivity; 16 import com.yctime.truelove.Utils.NetworkUtils; 17 import com.yctime.truelove.login.R; 18 19 import java.util.ArrayList; 20 21 22 /** 23 * A simple {@link Fragment} subclass. 24 */ 25 public class HomeReDuFragment extends BaseFragment { 26 27 private RecyclerView mRecyclerView; 28 private GridAdapter_Redu gridReDuAdapter; 29 // 服务器端一共多少条数据 30 private static final int TOTAL_COUNTER = 50; 31 // 每一页展示多少条数据 32 private static final int REQUEST_COUNT = 12; 33 // 已经获取到多少条数据了 34 private int mCurrentCounter = 0; 35 //模拟的数据源 36 private ArrayList<String> dataList; 37 38 39 protected LoadingFooter.FooterState mState = LoadingFooter.FooterState.Normal; 40 41 protected void setState(LoadingFooter.FooterState mState) { 42 this.mState = mState; 43 ((MainActivity) mContext).runOnUiThread(new Runnable() { 44 @Override 45 public void run() { 46 changeAdaperState(); 47 } 48 }); 49 } 50 51 //改变底部bottom的样式 52 protected void changeAdaperState() { 53 if (gridReDuAdapter != null && gridReDuAdapter.mFooterHolder != null) { 54 gridReDuAdapter.mFooterHolder.setData(mState); 55 } 56 } 57 58 public HomeReDuFragment() { 59 } 60 61 62 @Override 63 protected View initView() { 64 View mView = LayoutInflater.from(mContext).inflate(R.layout.homepage_viewpager_item_redu, null); 65 mRecyclerView = (RecyclerView) mView.findViewById(R.id.home_page_recyclerview); 66 return mView; 67 } 68 69 @Override 70 protected void initData() { 71 initGridView(); 72 } 73 74 75 private View initGridView() { 76 mRecyclerView.setHasFixedSize(true); 77 //滑动暂停加载网络图片,而且可以监听recycler是否滑动到底部 78 mRecyclerView.addOnScrollListener(mOnScrollListener); 79 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); 80 gridReDuAdapter = new GridAdapter_Redu(mContext); 81 gridReDuAdapter.addAll(getRemoteData()); 82 mRecyclerView.setAdapter(gridReDuAdapter); 83 GridLayoutManager layoutManager = new GridLayoutManager(mContext, 3); 84 layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 85 layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 86 @Override 87 public int getSpanSize(int position) { 88 //如果是最后一个item,则设置占据3列,否则占据1列 89 boolean isFooter = position == gridReDuAdapter.getItemCount() - 1; 90 return isFooter ? 3 : 1; 91 } 92 }); 93 mRecyclerView.setLayoutManager(layoutManager); 94 return mRecyclerView; 95 } 96 97 private EndlessRecyclerOnScrollListener mOnScrollListener = new EndlessRecyclerOnScrollListener() { 98 @Override 99 public void onLoadNextPage(View view) { 100 super.onLoadNextPage(view); 101 102 if (mState == LoadingFooter.FooterState.Loading) { 103 Log.d("@TAG", "the state is Loading, just wait.."); 104 return; 105 } 106 107 if (mCurrentCounter < TOTAL_COUNTER) { 108 // loading more 109 requestData(); 110 Log.d("TAG", "请求数据"); 111 } else { 112 //the end 113 setState(LoadingFooter.FooterState.TheEnd); 114 } 115 } 116 }; 117 118 119 /** 120 * 模拟请求网络 121 */ 122 private void requestData() { 123 setState(LoadingFooter.FooterState.Loading); 124 new Thread() { 125 @Override 126 public void run() { 127 super.run(); 128 try { 129 Thread.sleep(1000); 130 } catch (InterruptedException e) { 131 e.printStackTrace(); 132 } 133 if (NetworkUtils.isNetAvailable(mContext)) { 134 //模拟请求远程数据 135 gridReDuAdapter.addAll(getRemoteData()); 136 //加载完毕时 137 setState(LoadingFooter.FooterState.Normal); 138 Log.d("TAG", mCurrentCounter + ""); 139 } else { 140 //模拟一下网络请求失败的情况 141 setState(LoadingFooter.FooterState.NetWorkError); 142 } 143 } 144 }.start(); 145 } 146 147 //模拟请求数据 148 private ArrayList<String> getRemoteData() { 149 if (dataList == null) 150 dataList = new ArrayList<>(); 151 //每次都清空一下 152 dataList.clear(); 153 //要减去adapter最后一页 154 for (int i = 0; i < REQUEST_COUNT; i++) { 155 if (dataList.size() + mCurrentCounter >= TOTAL_COUNTER) { 156 break; 157 } 158 dataList.add("账号" + (mCurrentCounter + i)); 159 } 160 mCurrentCounter += dataList.size(); 161 return dataList; 162 } 163 164 165 }
![](/assets/blank.gif)
需要注意的是这个方法:
//改变底部bottom的样式protected void changeAdaperState() {if (gridReDuAdapter != null && gridReDuAdapter.mFooterHolder != null) {gridReDuAdapter.mFooterHolder.setData(mState);}}
Adapter的应用调用Adapter里面的方法,来切换Adaper的样式。 Adapter完整代码:
![](/assets/blank.gif)
1 package com.yctime.truelove.fragment; 2 3 import android.content.Context; 4 import android.content.Intent; 5 import android.support.v7.widget.RecyclerView; 6 import android.util.Log; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.view.ViewGroup; 10 import android.widget.ImageView; 11 import android.widget.TextView; 12 13 import com.yctime.truelove.ImageLoader.MyImageLoader; 14 import com.yctime.truelove.ImageLoader.UILImageLoader; 15 import com.yctime.truelove.LoadMore.LoadingFooter; 16 import com.yctime.truelove.drawer.MyZoneActivity; 17 import com.yctime.truelove.login.R; 18 19 import java.util.ArrayList; 20 21 22 public class GridAdapter_Redu extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 23 24 25 public String[] imgUrls = { 26 "http://img5.duitang.com/uploads/item/201402/22/20140222113830_X3ddd.jpeg", 27 "http://v1.qzone.cc/avatar/201403/01/10/36/531147afa4197738.jpg!200x200.jpg", 28 "http://g.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=e4d7ed147af40ad115b1cfe7621c3de9/b7fd5266d016092445b47837d50735fae6cd340d.jpg", 29 "http://img5q.duitang.com/uploads/item/201502/19/20150219182507_vGVaK.jpeg", 30 "http://p1.qqyou.com/touxiang/uploadpic/2013-3/12/2013031212190118646.jpg", 31 "http://img5.duitang.com/uploads/item/201412/08/20141208221323_YVJFk.png", 32 "http://cdn.duitang.com/uploads/item/201408/02/20140802222651_GWuU2.png", 33 "http://ent.dzwww.com/yulezhuanti/mtcbg/201510/W020151027467479100669.jpg", 34 "http://p1.qqyou.com/touxiang/uploadpic/2013-3/10/2013031009323656495.jpg", 35 "http://p1.qqyou.com/touxiang/uploadpic/2013-3/12/2013031212295986807.jpg", 36 "http://f.hiphotos.baidu.com/zhidao/wh%3D600%2C800/sign=10742594d739b6004d9b07b1d9601912/9f2f070828381f30ec9eabdeab014c086f06f0c5.jpg", 37 "http://a.hiphotos.baidu.com/zhidao/wh%3D600%2C800/sign=5bda8a18a71ea8d38a777c02a73a1c76/5882b2b7d0a20cf4598dc37c77094b36acaf9977.jpg", 38 "http://a1.att.hudong.com/36/98/300001051406133039983418031.jpg" 39 }; 40 public Context context; 41 MyImageLoader imageLoader = new UILImageLoader(); 42 private ArrayList<String> dataList = new ArrayList<>(); 43 44 45 private final int NORMALLAYOUT = 0; 46 private final int FOOTERLAYOUT = 1; 47 public FooterHolder mFooterHolder; 48 49 public GridAdapter_Redu(Context context) { 50 this.context = context; 51 } 52 53 public void addAll(ArrayList<String> list) { 54 int lastIndex = this.dataList.size(); 55 if (this.dataList.addAll(list)) { 56 notifyItemRangeInserted(lastIndex, list.size()); 57 } 58 } 59 60 @Override 61 public int getItemViewType(int position) { 62 if (position == dataList.size()) 63 return FOOTERLAYOUT; 64 else 65 return NORMALLAYOUT; 66 } 67 68 69 @Override 70 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 71 View view; 72 if (viewType == NORMALLAYOUT) { 73 view = LayoutInflater.from(context).inflate(R.layout.grid_redu_item, parent, false); 74 return new NormalHolder(view); 75 } else { 76 view = LayoutInflater.from(context).inflate(R.layout.sample_common_list_footer, parent, false); 77 mFooterHolder = new FooterHolder(view); 78 return mFooterHolder; 79 } 80 } 81 82 @Override 83 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 84 if (holder instanceof NormalHolder) { 85 //点击事件 86 holder.itemView.setOnClickListener(new View.OnClickListener() { 87 @Override 88 public void onClick(View v) { 89 Intent intent = new Intent(context, MyZoneActivity.class); 90 context.startActivity(intent); 91 } 92 }); 93 ((NormalHolder) holder).setData(position); 94 } 95 } 96 97 @Override 98 public int getItemCount() { 99 return dataList.size() + 1; 100 } 101 102 103 class NormalHolder extends RecyclerView.ViewHolder { 104 ImageView img; 105 TextView name; 106 107 public NormalHolder(View itemView) { 108 super(itemView); 109 img = (ImageView) itemView.findViewById(R.id.homepage_grid_picpic); 110 name = (TextView) itemView.findViewById(R.id.homepage_grid_name); 111 } 112 113 public void setData(int position) { 114 imageLoader.displayImage(context, imgUrls[position % imgUrls.length], img); 115 name.setText(dataList.get(position)); 116 } 117 } 118 119 public class FooterHolder extends RecyclerView.ViewHolder { 120 View mLoadingViewstubstub; 121 View mEndViewstub; 122 View mNetworkErrorViewstub; 123 124 public FooterHolder(View itemView) { 125 super(itemView); 126 mLoadingViewstubstub = itemView.findViewById(R.id.loading_viewstub); 127 mEndViewstub = itemView.findViewById(R.id.end_viewstub); 128 mNetworkErrorViewstub = itemView.findViewById(R.id.network_error_viewstub); 129 } 130 131 //根据传过来的status控制哪个状态可见 132 public void setData(LoadingFooter.FooterState status) { 133 Log.d("TAG", "reduAdapter" + status + ""); 134 switch (status) { 135 case Normal: 136 setAllGone(); 137 break; 138 case Loading: 139 setAllGone(); 140 mLoadingViewstubstub.setVisibility(View.VISIBLE); 141 break; 142 case TheEnd: 143 setAllGone(); 144 mEndViewstub.setVisibility(View.VISIBLE); 145 break; 146 case NetWorkError: 147 setAllGone(); 148 mNetworkErrorViewstub.setVisibility(View.VISIBLE); 149 break; 150 default: 151 break; 152 } 153 154 } 155 156 //全部不可见 157 void setAllGone() { 158 if (mLoadingViewstubstub != null) { 159 mLoadingViewstubstub.setVisibility(View.GONE); 160 } 161 if (mEndViewstub != null) { 162 mEndViewstub.setVisibility(View.GONE); 163 } 164 if (mNetworkErrorViewstub != null) { 165 mNetworkErrorViewstub.setVisibility(View.GONE); 166 } 167 } 168 169 } 170 171 }
![](/assets/blank.gif)
运行效果:
Android5.0新特性:RecyclerView实现上拉加载更多相关推荐
- Android使用RecyclerView实现上拉加载更多,下拉刷新,分组显示
项目地址:点击打开链接(https://github.com/MrGaoGang/luckly_recyclerview) 使用RecyclerView封装headerview,footerView, ...
- RecyclerView实现上拉加载更多的正确姿势
最近项目上的需求需要实现下拉刷新和上拉加载更多的功能,RecyclerView下拉刷新我相信安卓的同学都会做,无非是利用SwipeRefreshLayout,然后给swipeRefreshLayout ...
- android中如何实现上拉加载更多功能(建议收藏)
上拉加载更多功能实际上就是给RecyclerView增加一个FooterView,然后通过判断是否滑动到了最后一条Item,来控制FooterView的显示和隐藏,接下来我们来看下如何实现: 一.给A ...
- Flutter ListView 下拉刷新与上拉加载更多
ListView 下拉刷新与上拉加载更多 import 'dart:async'; import 'package:flutter/material.dart';/*** 有状态StatefulWid ...
- BaseRecyclerViewAdapterHelper源码解读(四) 上拉加载更多
上拉加载 上拉加载无需监听滑动事件,可自定义加载布局,显示异常提示,自定义异常提示. 此篇文章为BaseRecyclerViewAdapterHelper源码解读第四篇,开源库地址,如果没有看过之前3 ...
- Flutter listview下拉刷新 上拉加载更多 功能实现
下拉刷新 在Flutter中系统已经为我们提供了google material design的刷新功能 , 样式与原生Android一样. 我们可以使用RefreshIndicator组件来实现Flu ...
- android官方上拉加载,Android-RecycleView上拉加载更多
5.0之后 推出的RecycleView来代替ListView,可以说RecycleView和ListView比起有过之而无不及,下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基 ...
- 开发者头条(五):实现recyclerview的上拉加载 + 下拉刷新
学习Ansen的博客,原文:带你实现开发者头条APP(五)–RecyclerView下拉刷新上拉加载 ,这一篇写的很详细. 知识点 今天主要是实现recyclerview的上拉加载跟多和下拉刷新,依赖 ...
- Android RecyclerView封装下拉刷新与上拉加载更多
1 scanlistlibrary 基础组件说明(基于 RecyclerView的封装) 基本数据列表(支持下拉刷新与上拉加载更多) 九宫格数据显示封装(支持下拉刷新与上拉加载更多) 瀑布流数据显示封 ...
- RecyclerView的基础使用 +点击添加列表数据 +下拉刷新、上拉加载更多
一.RecyclerView的基础使用. 第一步:添加recyclerview控件. 第二步:创建布局文件(xml) + 单独的类控制布局里面的控件(MyViewHolder). 第三步:创建一个适配 ...
最新文章
- SVN 问题解决之 The XML response contains invalid XML
- Android Binder 分析——数据传递者(Parcel)
- html 字段大小,html td标签 限制字符长度
- 专题突破二之优先队列、st表——,Running Median,Sequence,Buy Low Sell High,数据备份,超级钢琴,ZQC的手办
- 深入理解InnoDB(8)—单表访问
- bilibili 韩顺平Java后端学习路线
- amos里CFA可行性辨别结果怎么看_本科毕业论文做问卷和数据分析应该怎么着手?(1)...
- 【AI识人】OpenPose:实时多人2D姿态估计 | 附视频测试及源码链接
- android_studio运行,Android Studio怎么运行程序?
- 网卡驱动:传输超时watchdog_timeo/ndo_tx_timeout
- CSDN竞赛6期题解
- html表格打印填充分页,window.print()页面打印之表格内容分页填充进行分页打印
- Latex表格线宽修改方法以及内容左对齐。
- LTspice基础教程-003.LTspice工具栏使用介绍
- 区块链---双花问题
- 最美的七律却不讲规则
- 互联网史-chinaren与校内
- 利用Python进行王者荣耀壁纸下载
- Xdoc 水印 解决方式
- 滑动(左滑右滑加载下一页)
热门文章
- 多个门店相继火爆开业,海底捞的“升级版”加速全国布局
- Cloud 团队:让 TiDB 在云上跳舞 | PingCAP 招聘季
- TSMaster1.4.2补丁包发布
- Python数据存取详解
- UCanCode发布跨平台开源组态\ 建模\仿真\工控VX++ 2021
- 黑苹果Mac OS 12镜像下载 DMG
- com.android.pngp.tln,杂七杂八的记录
- 小程序 全屏滑动【亲测有效】
- 腾达f6虚拟服务器,腾达(Tenda)F6路由器无线wifi设置
- 镁光闪存颗粒对照表_最全的内存颗粒编码规则说明,教你看穿内存条到底用的什么颗粒...