今天给大家讲的是如何自定义下拉的ListView实现支付宝账单的效果,月份是需要悬浮的,然后没一个月归为一类,先看一个效果图吧。

场景:后台下发的数据就是一个List<对象>,考虑到实际情况,还需要做下拉的分页操作,所以,基于上面的情况,我们需要自定义一个可以拦截月份的view。

先定义一个FooterView类。

public class ListViewFooter extends LinearLayout {public final static int STATE_NORMAL = 0;public final static int STATE_READY = 1;public final static int STATE_LOADING = 2;private Context mContext;private View mContentView;private View mProgressBar;private TextView mFootTextView;public ListViewFooter(Context context) {super(context);initView(context);}public ListViewFooter(Context context, AttributeSet attrs) {super(context, attrs);initView(context);}//下拉状态处理public void setState(int state) {mFootTextView.setVisibility(View.INVISIBLE);mProgressBar.setVisibility(View.GONE);if (state == STATE_READY) {mFootTextView.setVisibility(View.VISIBLE);mProgressBar.setVisibility(View.GONE);mFootTextView.setText(R.string.pull_footer_hint_ready);} else if (state == STATE_LOADING) {mProgressBar.setVisibility(View.VISIBLE);mFootTextView.setVisibility(View.VISIBLE);} else {mFootTextView.setVisibility(View.VISIBLE);mProgressBar.setVisibility(View.GONE);mFootTextView.setText(R.string.pull_footer_hint_normal);}}public void setBottomMargin(int height) {if (height < 0) return ;LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();lp.bottomMargin = height;mContentView.setLayoutParams(lp);}public int getBottomMargin() {LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();return lp.bottomMargin;}public void normal() {mFootTextView.setVisibility(View.VISIBLE);mProgressBar.setVisibility(View.GONE);}public void loading() {mFootTextView.setVisibility(View.GONE);mProgressBar.setVisibility(View.VISIBLE);}public void hide() {LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();lp.height = 0;mContentView.setLayoutParams(lp);}public void show() {LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();lp.height = LayoutParams.WRAP_CONTENT;mContentView.setLayoutParams(lp);}private void initView(Context context) {mContext = context;LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_listview_footer, null);addView(moreView);moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));mContentView = moreView.findViewById(R.id.footer_view);mProgressBar = moreView.findViewById(R.id.footer_progressbar);mFootTextView = (TextView)moreView.findViewById(R.id.footer_textview);}public TextView getmFootTextView() {return mFootTextView;}
}

然后我们通过继承自ListViwe实现一个下拉的PullListView类。

public class PullFreshListView extends ListView implements OnScrollListener {private float mLastY = -1;private Scroller mScroller;private OnScrollListener mScrollListener;private ListViewPlusListener mListViewListener;private boolean mPullRefreshing = false;private ListViewFooter mFooterView;private boolean mEnablePullLoad;private boolean mPullLoading;private boolean mIsFooterReady = false;private int mTotalItemCount;private int mScrollBack;private int minItemCount=3;private final static int SCROLLBACK_HEADER = 0;private final static int SCROLLBACK_FOOTER = 1;private final static int SCROLL_DURATION = 400;private final static int PULL_LOAD_MORE_DELTA = 50;private final static float OFFSET_RADIO = 1.8f;public PullFreshListView(Context context) {super(context);initWithContext(context);}public PullFreshListView(Context context, AttributeSet attrs) {super(context, attrs);initWithContext(context);}public PullFreshListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initWithContext(context);}private void initWithContext(Context context) {mScroller = new Scroller(context, new DecelerateInterpolator());super.setOnScrollListener(this);mFooterView = new ListViewFooter(context);}@Overridepublic void setAdapter(ListAdapter adapter) {if (mIsFooterReady == false) {mIsFooterReady = true;addFooterView(mFooterView);}super.setAdapter(adapter);}public void setLoadEnable(boolean enable) {mEnablePullLoad = enable;if (!mEnablePullLoad) {mFooterView.hide();mFooterView.setOnClickListener(null);setFooterDividersEnabled(false);} else {mPullLoading = false;mFooterView.show();mFooterView.setState(ListViewFooter.STATE_NORMAL);setFooterDividersEnabled(true);mFooterView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {startLoadMore();}});}}public void stopLoadMore() {if (mPullLoading == true) {mPullLoading = false;mFooterView.setState(ListViewFooter.STATE_NORMAL);}}private void invokeOnScrolling() {if (mScrollListener instanceof OnXScrollListener) {OnXScrollListener l = (OnXScrollListener) mScrollListener;l.onXScrolling(this);}}private void resetHeaderHeight() {invalidate();}private void updateFooterHeight(float delta) {int height = mFooterView.getBottomMargin() + (int) delta;if (mEnablePullLoad && !mPullLoading) {if (height > PULL_LOAD_MORE_DELTA) {mFooterView.setState(ListViewFooter.STATE_READY);} else {mFooterView.setState(ListViewFooter.STATE_NORMAL);}}mFooterView.setBottomMargin(height);}private void resetFooterHeight() {int bottomMargin = mFooterView.getBottomMargin();if (bottomMargin > 0) {mScrollBack = SCROLLBACK_FOOTER;mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,SCROLL_DURATION);invalidate();}}private void startLoadMore() {mPullLoading = true;mFooterView.setState(ListViewFooter.STATE_LOADING);if (mListViewListener != null) {mListViewListener.onLoadMore();}}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (mLastY == -1) {mLastY = ev.getRawY();}switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:mLastY = ev.getRawY();break;case MotionEvent.ACTION_MOVE:final float deltaY = ev.getRawY() - mLastY;mLastY = ev.getRawY();if (getLastVisiblePosition() == mTotalItemCount - 1&& (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {updateFooterHeight(-deltaY / OFFSET_RADIO);}break;default:mLastY = -1;if (getFirstVisiblePosition() == 0) {resetHeaderHeight();} else if (getLastVisiblePosition() == mTotalItemCount - 1) {if (mEnablePullLoad&& mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA&& !mPullLoading) {startLoadMore();}resetFooterHeight();}break;}return super.onTouchEvent(ev);}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {if (mScrollBack == SCROLLBACK_HEADER) {} else {mFooterView.setBottomMargin(mScroller.getCurrY());}postInvalidate();invokeOnScrolling();}super.computeScroll();}@Overridepublic void setOnScrollListener(OnScrollListener l) {mScrollListener = l;}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (mScrollListener != null) {mScrollListener.onScrollStateChanged(view, scrollState);}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {if(mFooterView!=null){if (totalItemCount<minItemCount+2) {mFooterView.getmFootTextView().setText("");}else {if(mFooterView.getmFootTextView().getText().toString().equals(""))mFooterView.getmFootTextView().setText(getResources().getString(R.string.pull_footer_hint_normal));}}mTotalItemCount = totalItemCount;if (mScrollListener != null) {mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,totalItemCount);}}public void setListViewPlusListener(ListViewPlusListener l) {mListViewListener = l;}public interface OnXScrollListener extends OnScrollListener {void onXScrolling(View view);}public interface ListViewPlusListener {void onLoadMore();}}

最后要实现可以悬浮的效果,我们需要对布局的滑动的数据进行监听,具体请看代码:

public class PullStickyListView extends PullFreshListView {public  interface PinnedSectionListAdapter extends ListAdapter {boolean isItemViewTypePinned(int viewType);}static class PinnedSection {public View view;public int position;public long id;}private final Rect mTouchRect = new Rect();private final PointF mTouchPoint = new PointF();private int mTouchSlop;private View mTouchTarget;private MotionEvent mDownEvent;private GradientDrawable mShadowDrawable;private int mSectionsDistanceY;private int mShadowHeight;private OnScrollListener mDelegateOnScrollListener;private PinnedSection mRecycleSection;private PinnedSection mPinnedSection;private int mTranslateY;private final OnScrollListener mOnScrollListener = new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (mDelegateOnScrollListener != null) {mDelegateOnScrollListener.onScrollStateChanged(view, scrollState);}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {if (mDelegateOnScrollListener != null) {mDelegateOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);}ListAdapter adapter = getAdapter();if (adapter == null || visibleItemCount == 0) return;final boolean isFirstVisibleItemSection =isItemViewTypePinned(adapter, adapter.getItemViewType(firstVisibleItem));if (isFirstVisibleItemSection) {View sectionView = getChildAt(0);if (sectionView.getTop() == getPaddingTop()) {destroyPinnedShadow();} else {ensureShadowForPosition(firstVisibleItem, firstVisibleItem, visibleItemCount);}} else {int sectionPosition = findCurrentSectionPosition(firstVisibleItem);if (sectionPosition > -1) {ensureShadowForPosition(sectionPosition, firstVisibleItem, visibleItemCount);} else {destroyPinnedShadow();}}}};private final DataSetObserver mDataSetObserver = new DataSetObserver() {@Overridepublic void onChanged() {recreatePinnedShadow();}@Overridepublic void onInvalidated() {recreatePinnedShadow();}};public PullStickyListView(Context context, AttributeSet attrs) {super(context, attrs);initView();}public PullStickyListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initView();}private void initView() {setOnScrollListener(mOnScrollListener);mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
//        initShadow(true);}public void setShadowVisible(boolean visible) {initShadow(visible);if (mPinnedSection != null) {View v = mPinnedSection.view;invalidate(v.getLeft(), v.getTop(), v.getRight(), v.getBottom() + mShadowHeight);}}public void initShadow(boolean visible) {if (visible) {if (mShadowDrawable == null) {mShadowDrawable = new GradientDrawable(Orientation.TOP_BOTTOM,new int[]{Color.parseColor("#ffa0a0a0"), Color.parseColor("#50a0a0a0"), Color.parseColor("#00a0a0a0")});mShadowHeight = (int) (8 * getResources().getDisplayMetrics().density);}} else {if (mShadowDrawable != null) {mShadowDrawable = null;mShadowHeight = 0;}}}void createPinnedShadow(int position) {PinnedSection pinnedShadow = mRecycleSection;mRecycleSection = null;if (pinnedShadow == null) pinnedShadow = new PinnedSection();View pinnedView = getAdapter().getView(position, pinnedShadow.view, PullStickyListView.this);LayoutParams layoutParams = (LayoutParams) pinnedView.getLayoutParams();if (layoutParams == null) {layoutParams = (LayoutParams) generateDefaultLayoutParams();pinnedView.setLayoutParams(layoutParams);}int heightMode = MeasureSpec.getMode(layoutParams.height);int heightSize = MeasureSpec.getSize(layoutParams.height);if (heightMode == MeasureSpec.UNSPECIFIED) heightMode = MeasureSpec.EXACTLY;int maxHeight = getHeight() - getListPaddingTop() - getListPaddingBottom();if (heightSize > maxHeight) heightSize = maxHeight;// measure & layoutint ws = MeasureSpec.makeMeasureSpec(getWidth() - getListPaddingLeft() - getListPaddingRight(), MeasureSpec.EXACTLY);int hs = MeasureSpec.makeMeasureSpec(heightSize, heightMode);pinnedView.measure(ws, hs);pinnedView.layout(0, 0, pinnedView.getMeasuredWidth(), pinnedView.getMeasuredHeight());mTranslateY = 0;// initialize pinned shadowpinnedShadow.view = pinnedView;pinnedShadow.position = position;pinnedShadow.id = getAdapter().getItemId(position);// store pinned shadowmPinnedSection = pinnedShadow;}void destroyPinnedShadow() {if (mPinnedSection != null) {mRecycleSection = mPinnedSection;mPinnedSection = null;}}void ensureShadowForPosition(int sectionPosition, int firstVisibleItem, int visibleItemCount) {if (visibleItemCount < 2) {destroyPinnedShadow();return;}if (mPinnedSection != null&& mPinnedSection.position != sectionPosition) {destroyPinnedShadow();}if (mPinnedSection == null) {createPinnedShadow(sectionPosition);}int nextPosition = sectionPosition + 1;if (nextPosition < getCount()) {int nextSectionPosition = findFirstVisibleSectionPosition(nextPosition,visibleItemCount - (nextPosition - firstVisibleItem));if (nextSectionPosition > -1) {View nextSectionView = getChildAt(nextSectionPosition - firstVisibleItem);final int bottom = mPinnedSection.view.getBottom() + getPaddingTop();mSectionsDistanceY = nextSectionView.getTop() - bottom;if (mSectionsDistanceY < 0) {mTranslateY = mSectionsDistanceY;} else {mTranslateY = 0;}} else {mTranslateY = 0;mSectionsDistanceY = Integer.MAX_VALUE;}}}int findFirstVisibleSectionPosition(int firstVisibleItem, int visibleItemCount) {ListAdapter adapter = getAdapter();int adapterDataCount = adapter.getCount();if (getLastVisiblePosition() >= adapterDataCount)return -1;if (firstVisibleItem + visibleItemCount >= adapterDataCount) {//added to prevent index Outofbound (in case)visibleItemCount = adapterDataCount - firstVisibleItem;}for (int childIndex = 0; childIndex < visibleItemCount; childIndex++) {int position = firstVisibleItem + childIndex;int viewType = adapter.getItemViewType(position);if (isItemViewTypePinned(adapter, viewType)) return position;}return -1;}int findCurrentSectionPosition(int fromPosition) {ListAdapter adapter = getAdapter();if (fromPosition >= adapter.getCount()) return -1;if (adapter instanceof SectionIndexer) {SectionIndexer indexer = (SectionIndexer) adapter;int sectionPosition = indexer.getSectionForPosition(fromPosition);int itemPosition = indexer.getPositionForSection(sectionPosition);int typeView = adapter.getItemViewType(itemPosition);if (isItemViewTypePinned(adapter, typeView)) {return itemPosition;}}for (int position = fromPosition; position >= 0; position--) {int viewType = adapter.getItemViewType(position);if (isItemViewTypePinned(adapter, viewType)) return position;}return -1;}void recreatePinnedShadow() {destroyPinnedShadow();ListAdapter adapter = getAdapter();if (adapter != null && adapter.getCount() > 0) {int firstVisiblePosition = getFirstVisiblePosition();int sectionPosition = findCurrentSectionPosition(firstVisiblePosition);if (sectionPosition == -1) return;ensureShadowForPosition(sectionPosition,firstVisiblePosition, getLastVisiblePosition() - firstVisiblePosition);}}@Overridepublic void setOnScrollListener(OnScrollListener listener) {if (listener == mOnScrollListener) {super.setOnScrollListener(listener);} else {mDelegateOnScrollListener = listener;}}@Overridepublic void onRestoreInstanceState(Parcelable state) {super.onRestoreInstanceState(state);post(new Runnable() {@Overridepublic void run() {recreatePinnedShadow();}});}@Overridepublic void setAdapter(ListAdapter adapter) {if (adapter != null) {if (!(adapter instanceof PinnedSectionListAdapter))throw new IllegalArgumentException("Does your adapter implement PinnedSectionListAdapter?");if (adapter.getViewTypeCount() < 2)throw new IllegalArgumentException("Does your adapter handle at least two types" +" of views in getViewTypeCount() method: items and sections?");}ListAdapter oldAdapter = getAdapter();if (oldAdapter != null) oldAdapter.unregisterDataSetObserver(mDataSetObserver);if (adapter != null) adapter.registerDataSetObserver(mDataSetObserver);if (oldAdapter != adapter) destroyPinnedShadow();super.setAdapter(adapter);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (mPinnedSection != null) {int parentWidth = r - l - getPaddingLeft() - getPaddingRight();int shadowWidth = mPinnedSection.view.getWidth();if (parentWidth != shadowWidth) {recreatePinnedShadow();}}}@Overrideprotected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);if (mPinnedSection != null) {int pLeft = getListPaddingLeft();int pTop = getListPaddingTop();View view = mPinnedSection.view;canvas.save();int clipHeight = view.getHeight() +(mShadowDrawable == null ? 0 : Math.min(mShadowHeight, mSectionsDistanceY));canvas.clipRect(pLeft, pTop, pLeft + view.getWidth(), pTop + clipHeight);canvas.translate(pLeft, pTop + mTranslateY);drawChild(canvas, mPinnedSection.view, getDrawingTime());if (mShadowDrawable != null && mSectionsDistanceY > 0) {mShadowDrawable.setBounds(mPinnedSection.view.getLeft(),mPinnedSection.view.getBottom(),mPinnedSection.view.getRight(),mPinnedSection.view.getBottom() + mShadowHeight);mShadowDrawable.draw(canvas);}canvas.restore();}}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {final float x = ev.getX();final float y = ev.getY();final int action = ev.getAction();if (action == MotionEvent.ACTION_DOWN&& mTouchTarget == null&& mPinnedSection != null&& isPinnedViewTouched(mPinnedSection.view, x, y)) {mTouchTarget = mPinnedSection.view;mTouchPoint.x = x;mTouchPoint.y = y;mDownEvent = MotionEvent.obtain(ev);}if (mTouchTarget != null) {if (isPinnedViewTouched(mTouchTarget, x, y)) {mTouchTarget.dispatchTouchEvent(ev);}if (action == MotionEvent.ACTION_UP) {super.dispatchTouchEvent(ev);performPinnedItemClick();clearTouchTarget();} else if (action == MotionEvent.ACTION_CANCEL) {clearTouchTarget();} else if (action == MotionEvent.ACTION_MOVE) {if (Math.abs(y - mTouchPoint.y) > mTouchSlop) {MotionEvent event = MotionEvent.obtain(ev);event.setAction(MotionEvent.ACTION_CANCEL);mTouchTarget.dispatchTouchEvent(event);event.recycle();super.dispatchTouchEvent(mDownEvent);super.dispatchTouchEvent(ev);clearTouchTarget();}}return true;}return super.dispatchTouchEvent(ev);}private boolean isPinnedViewTouched(View view, float x, float y) {view.getHitRect(mTouchRect);mTouchRect.top += mTranslateY;mTouchRect.bottom += mTranslateY + getPaddingTop();mTouchRect.left += getPaddingLeft();mTouchRect.right -= getPaddingRight();return mTouchRect.contains((int) x, (int) y);}private void clearTouchTarget() {mTouchTarget = null;if (mDownEvent != null) {mDownEvent.recycle();mDownEvent = null;}}private boolean performPinnedItemClick() {if (mPinnedSection == null) return false;OnItemClickListener listener = getOnItemClickListener();if (listener != null && getAdapter().isEnabled(mPinnedSection.position)) {View view = mPinnedSection.view;playSoundEffect(SoundEffectConstants.CLICK);if (view != null) {view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);}listener.onItemClick(this, view, mPinnedSection.position, mPinnedSection.id);return true;}return false;}public static boolean isItemViewTypePinned(ListAdapter adapter, int viewType) {if (adapter instanceof HeaderViewListAdapter) {adapter = ((HeaderViewListAdapter) adapter).getWrappedAdapter();}return ((PinnedSectionListAdapter) adapter).isItemViewTypePinned(viewType);}}

附:仿支付宝账单流水
饼状图:http://blog.csdn.net/kuangxiaoguo0123/article/details/53282809

Android实现仿支付宝流水相关推荐

  1. android 自定义饼图半径不定,【Android】仿支付宝账单统计饼状图的自定义view

    仿支付宝统计饼状图的自定义view,如下图: 项目地址:https://github.com/bigeyechou/CustomViewCollection 目录:customviewcollecti ...

  2. Android中仿支付宝月账单view

    前言 昨夜同门云集推杯又换盏,今朝茶凉酒寒豪言成笑谈.半生累,尽徒然,碑文完美有谁看,隐居山水之间誓与浮名散. 简介 今天给大家带来的是支付宝的月账单view的实现,看到标题,你可能会觉得是自定义vi ...

  3. android ‘低’仿支付宝我的应用功能!(含完整Demo)

    '低'配支付宝我的应用功能 我的环境 界面和需求分析 代码思路 最近项目需求,要求我仿造支付宝功能,写一个类似的功能,想了1天,实操2天终于搞定了!! 先来看看实现的效果: 效果一 效果二 效果三 我 ...

  4. Android 高仿支付宝二维码扫描动画实现 3分钟学会 人脸识别扫描线

    原理: 1.把方框的位置在xml中布置好 2.把扫描线的图片也布置好 3.用平移动画,移动y轴,循环的次数反复. 不过我网上搜了搜很多方法都是实时绘制出来的,计算点的位置然后重绘出来.我的第一感觉是完 ...

  5. android自定义金额输入键盘_Android 自定义控件 - 仿支付宝数字键盘

    原标题:Android 自定义控件 - 仿支付宝数字键盘 简介 在一些带有支付功能的 App 中,输入的密码一般只能是纯数字,虽然我们可以指定 EditText 输入框只能输入数字,但是为了提供用户的 ...

  6. Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View...

    Android特效专辑(十二)--仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术 ...

  7. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...

  8. Android开发笔记(一百四十四)高仿支付宝的头部伸缩动画

    Android5.0推出的MaterialDesign库包含了处理头部工具栏的多个控件,不但允许自定义顶部导航栏,而且导航栏高度是可以伸缩的.如此一来,一方面导航栏能够放得下更多控件,另一方面在用户想 ...

  9. Android 控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现

    Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现 关注finddreams:http://blog.csdn.net/finddreams/articl ...

最新文章

  1. ABAP UDO generation report
  2. Oracle 11g的安装详细过程
  3. 【引用】MySQL定时任务
  4. 三运放差分放大电路分析_运放19——三运放仪表放大器工作原理分析
  5. 为什么c语言运行比python快
  6. 伺服驱动器PID调节
  7. word字体号对应的磅数
  8. 计算机为什么采用二进制?
  9. 使用Pytorch搭建U-Net网络并基于DRIVE数据集训练(语义分割)学习笔记
  10. 超简单的 VIM 练级攻略
  11. ker矩阵是什么意思_矩阵形式下的最小二乘法推导
  12. 安霸linux开发板,安霸 ubuntu开发环境搭建
  13. 学习的榜样,进步的力量(来自中国人才热线的简历)
  14. 低温烹饪过程中真空压力的自动控制
  15. Python实现北邮人论坛模拟登录
  16. Android API开发之TTS开发之Android TTS简单使用
  17. 滤波器组共空间模式(Filter Bank Common Spatial Pattern,FBCSP)
  18. 操作系统和并发的爱恨纠葛
  19. loadrunner接口压测脚本编写模板
  20. 友情提醒:新办理的手机号没事千万别换卡槽,否则容易停机!

热门文章

  1. 知然算法【2】灰色模型GM(1,1)
  2. 校招总结—FPGA从入门到放弃
  3. 反向比例运算电路微分关系_干货|电源工程师必备求生技能——经典20种模拟电路...
  4. 反向比例运算电路微分关系_电气必备20个经典电路,老电工必看!
  5. 新手使用APICloud可视化开发搭建商城主页
  6. 基于ipfs和eth的视频分享应用开发经历(一)
  7. Transformer图解
  8. 有序数组二分查找最接近的值
  9. 九个UPS不间断电源常见故障分析
  10. matlab只显示y一部分,突出显示matlab图的部分内容