今天看了一篇文章是搞ListView动态悬浮header的, 我又结合了WheelView的item的绘制方式,最终终于有了这篇博客,在讲解实现方式之前,我们先来看看要实现的效果。

要实现这种效果有很多方式,普通的布局, 给ListView添加header都ok,而且也有很简单,不过现在我们不打算这么做。记得在看WheelView的时候,他的View里竟然有一个ViewGroup,当时感觉好神奇,这玩意怎么绘制出来呢? 哦, 原来他是在onMeasure、onLayout、onDraw中分别调用了那个ViewGroup的measure、layout、draw方法,这种方式我还是第一次见到! 虽然过去很长时间了,不过今天在看到这篇给ListView添加动态悬浮header的时候我突然想起了这种方式,于是…开干!

如何干? 现在我们重写了一份ListView,虽然这种方式绝壁不是好的, 但是为了使用上面提到的方式,忍了!

public class StickyListView extends ListView implements AbsListView.OnScrollListener {/**隐藏的延迟时间*/public static final int DURATION = 1000;/**header view*/private View mStickyHeaderView;/**可以设置header的adapter*/private StickyListAdapter mAdapter;/** 是否正在滑动*/private boolean scrolled;/** 用户是不是touch屏幕*/private boolean touched;/**保存ListView原始的padding*/private int[] mPaddings = new int[4];/** 设置scroll监听*/private AbsListView.OnScrollListener mScrollListener;public StickyListView(Context context) {super(context);init();}public StickyListView(Context context, AttributeSet attrs) {super(context, attrs);init();}public StickyListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() {// 保存原始的paddingmPaddings[0] = getPaddingLeft();mPaddings[1] = getPaddingTop();mPaddings[2] = getPaddingRight();mPaddings[3] = getPaddingBottom();// 调用super.setOnScrollListener// 因为下面我们重写了setOnScrollListenersuper.setOnScrollListener(this);}...
}

上面的代码,除了定义变量外, 我们还注意到了init方法,在这个方法中我们除了保存一个这个ListView的padding以外,还调用了super.setOnScrollListener(this),这里是有学问的,为什么是super呢?因为下面我们将要重写setOnScrollListener方法并且覆盖默认的逻辑,这样做的目的是:别让使用者在setOnScrollListener后覆盖了我们设置的默认监听。在变量中你可能还注意到了一个StickyListAdapter这是我们继承了BaseAdapter并且做了扩展的adapter,扩展的内容仅仅是为了获取header,

public void setAdapter(StickyListAdapter adapter) {super.setAdapter(adapter);mAdapter = adapter;mStickyHeaderView = adapter.getHeaderView(null, this, 0);hideHeader();
}public static abstract class StickyListAdapter extends BaseAdapter {public abstract View getHeaderView(View convertView, ViewGroup container, int position);
}

setAdapter中我们获取了第一个headerView,这里主要是为了测量,布局使用, 那下面我们就来看看如何为这个headerView测量和布局的。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);if(mStickyHeaderView != null) {mStickyHeaderView.measure(widthMeasureSpec,MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST));}
}@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if(mStickyHeaderView != null) {mStickyHeaderView.layout(getPaddingLeft(), getPaddingTop(),mStickyHeaderView.getMeasuredWidth() + getPaddingLeft(),mStickyHeaderView.getMeasuredHeight() + getPaddingTop());}
}

在ListView的onMeasureonLayout中我们直接调用了headerView的measurelayout,而且在全局代码中没有任何代码是将这个headerView添加到任何view中的。那他怎么显示出来呢? 不要着急,我们在看绘制的时候就明白了。
再来看看测量和布局,这里很简单,就是将这个headerView布局到ListView的padding以内的位置。so,easy。 那赶紧来看看如何绘制到屏幕的吧!

@Override
public void draw(Canvas canvas) {super.draw(canvas);if(mStickyHeaderView.getVisibility() == View.VISIBLE) mStickyHeaderView.draw(canvas);
}

我们直接调用了这个view的draw方法,但是在这之前我们需要自己去判断可见了,因为绘制并不是一层层的分发下来的,而是我们自己调用的。

现在,我们的header就可以显示出来了,并且可以显示到正确的位置了,那如何改变header的内容呢?为了灵活性,设置内容我们交给用户去做,我们仅仅是调用mAdapter.getHeaderView(mStickyHeaderView, this, firstVisibleItem)就ok啦,在哪调用?当然是滑动的时候了。

private Runnable mHideTask = new Runnable() {public void run() {hideHeader();smoothScrollBy(mStickyHeaderView.getMeasuredHeight(), 0);}
};public void onScrollStateChanged(AbsListView view, int scrollState) {if(mScrollListener != null) mScrollListener.onScrollStateChanged(view, scrollState);removeCallbacks(mHideTask);if(touched && scrolled && scrollState == SCROLL_STATE_IDLE) {scrolled = false;touched = false;postDelayed(mHideTask, DURATION);}
}public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {if(mScrollListener != null) mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);if(touched && mAdapter != null) {mStickyHeaderView = mAdapter.getHeaderView(mStickyHeaderView, this, firstVisibleItem);if(!scrolled) {scrolled = true;showHeader();}}
}

重点来看看touched,这里为什么要这么一个boolean变量呢? 主要是在mHideTask中,我们调用了smoothScrollBy这个方法会导致监听事件的回调,如果没有这个boolean变量,那我们的滑动就可能一直进行下去了,这个touched变量正是表示了滑动是由用户发起的,而不是自动滑动的。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:touched = true;break;}return super.dispatchTouchEvent(ev);
}

到现在我们的代码就基本完成了,下面我们来写一个试试吧。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="org.loader.stickyheaderlistview.MainActivity" ><org.loader.stickyheaderlistview.StickyListView
        android:id="@+id/list"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final StickyListView listView = (StickyListView) findViewById(R.id.list);listView.setAdapter(new MyAdapter());}private class MyAdapter extends StickyListAdapter {public int getCount() {return STRS.length;}public Object getItem(int position) {return STRS[position];}public long getItemId(int position) {return position;}public View getView(int position, View convertView, ViewGroup parent) {final Holder holder;if(convertView == null) {convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);holder = new Holder(convertView);convertView.setTag(holder);}else {holder = (Holder) convertView.getTag();}holder.textView.setText(STRS[position]);return convertView;}@Overridepublic View getHeaderView(View convertView, ViewGroup container,int position) {if(convertView == null) {convertView = LayoutInflater.from(container.getContext()).inflate(R.layout.header, container, false);}TextView header = (TextView) convertView.findViewById(R.id.header);char headerText = STRS[position].charAt(0);header.setText(String.valueOf(headerText));return convertView;}class Holder {TextView textView;public Holder(View itemView) {textView = (TextView) itemView.findViewById(R.id.item);}}}public static final String[] STRS = {"Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi","Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale","Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese","Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell","Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc","Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss","Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon","Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase","Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese","Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy","Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille","Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore","Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)","Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves","Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur","Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon","Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin","Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)","Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine","Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza","Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)","Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta","Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie","Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat","Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano","Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain","Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou","Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar","Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno","Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack","Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper","Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)","Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese","Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza","Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley","Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino","Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina","Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby","Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin","Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester","Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue","Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz","Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich","Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue","Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle","Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia","Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis","Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus","Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison","Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois","Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse","Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese","Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise","Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra","Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola","Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost","Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel","Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve","Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi","Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti","Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve","Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster","Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg","Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa","Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine","Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese","Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere","La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire","Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou","Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger","Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings","Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse","Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam","Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego","Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin","Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)","Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse","Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda","Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte","Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio","Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne","Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)","Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster","Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel","Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca","Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre","Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty","Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela","Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano","Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage","Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry","Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid","Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn","Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse","Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin","Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin","Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre","Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone","Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark","Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit","Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia","Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)","Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna","Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera","Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou","Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder","Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort","Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr","Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin","Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre","Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss","Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela","Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda","Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain","Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese","Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale","Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie","Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri","Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar","Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance","Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes","Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet","Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe","Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa","Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois","Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue","Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington","Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou","Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue","Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
}

哈哈, 数据借用的别人的,感谢一下那位哥们的辛勤劳动。重点在getHeaderView中,我们将第一个可见项的首字母作为header的内容,不过这里很灵活,你可以添加任意内容。

demo下载

ListView添加动态悬浮header的另类方式相关推荐

  1. Android开发之listview添加头布局(header)和脚布局(footer)的方法

    我们先说下添加的方法 方法一:正常添加lvCouponList.addHeaderView(headerView);lvCouponList.addFooterView(footerView); 方法 ...

  2. Android HorizontalScrollView 水平滑动 在listview上面动态添加图片

    Android HorizontalScrollView   水平滑动    listview 上动态添加图片 最近遇到了个 在listview展示广告的需要动态添加图片 如图: 使用了 horizo ...

  3. Android旋转切换条目,Android:当我添加动态新的ListView条目时,ListView中的旋转器会丢失它们的值...

    我的活动包含一个按钮和一个ListView. ListView包含Spinner和EditText视图.每次我想在Activity的ListView中插入一个新的行条目时,我都会使用该按钮. 我遵循了 ...

  4. python 类装饰器和继承_python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)...

    介绍装饰器.继承.元类.mixin,四种給类动态添加类属性和方法的方式 有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加. 1 #coding= ...

  5. gazebo中添加动态障碍物

    文章目录 gazebo 教程 gazebo 添加动态障碍物 gazebo添加动态障碍物插件 gazebo中动态障碍物实时pose gazebo 教程 gazebo github https://git ...

  6. Android ListView添加头部和尾部

    ListView添加头部和尾部: 头部布局:addHeaderView 尾部布局:addFooterView 使用java代码: //添加头部final View header = View.infl ...

  7. Flutter ListView (动态)列表组件、水平列表组件、图标组件详解

    Flutter ListView (动态)列表组件.水平列表组件.图标组件 Flutter ListView 基础列表组件.水平列表组件.图标组件 列表常见的几种情况: 垂直列表 垂直图文列表 横向列 ...

  8. 企业自研业务系统的登录如何添加动态口令,实施MFA双因子认证?

    一.背景需求 不少企业因业务需要会自己研发业务系统,为保护业务数据安全,首先要确保能访问到业务数据的人员"身份"安全可信. 企业自研业务系统的账号密码基本是 IT 管理员单独管理维 ...

  9. 利用腾讯云为静态页面添加“动态”相册

    title: 利用腾讯云为静态页面添加"动态"相册 date: 2019-11-24 10:52:34 tags: 腾讯云cos桶 Frontend categories: Fro ...

最新文章

  1. 一次失败的Pytorch模型量化尝试
  2. css样式表实验报告,css基本样式(二)
  3. 计算机设计大赛国奖作品_3. 需求分析
  4. OpenCV trackbar 避免使用全局变量
  5. 【搞事】HTTP文件传输服务器搭建|网站文件分享|HFSxCHFS用法
  6. 蒙特卡洛估值几种不同的计算方式(Python)
  7. html单元格溢出,excel如何超出单元格显示
  8. mysql备份文件如何还原数据库文件_数据库备份文件还原方法
  9. 微软语音识别引擎Speech
  10. LCD液晶屏连接方式有哪些呢及各自优缺点是什么?
  11. mobil连接数据的关键语句
  12. Smart3D初学者第二步:三维模型重建(1)
  13. Python二叉树详解笔记
  14. delphi 向窗体发送一个字符串_IoT Hub入门(2)模拟设备发送设备到云(d2c)的消息
  15. Windows11 文件管理器 很慢很卡怎么办
  16. Delegate委托的使用
  17. VIP看剧也要找好友砍一刀!网友喊话优酷:吃相越来越难看了
  18. Codeforces Round #262 (Div. 2)-A,B,C,D
  19. 批量修改World和PPT的文字格式、颜色、大小等
  20. CNN自定义图片分类(Pytorch)

热门文章

  1. 获取商品详细信息 通过API
  2. 深度学习工具(Netscope)
  3. 浅谈static_cast、dynamic_cast、const_cast、reinterpret_cast用法
  4. 【Axure原型分享】动态查看长图
  5. 常见的MAC算法PBOC_3DES_MAC,C语言实现(高效率,支持单片机)
  6. 在家赚钱的工作,这五种比较适合在家操作!
  7. navicat数据库管理软件延长试用期
  8. 神舟战神换cpu教程_神舟战神K540D-I7 D1 拆机 清灰 装内存 教程
  9. GIS底层开发、GIS前端开发和GIS后端开发有什么区别?
  10. 武汉云数时代网络科技有限公司代运营如何选择合适产品?