更多Android高级架构进阶视频学习请点击:

哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibili​space.bilibili.com

本篇文章将从ViewPager来介绍常用View:

文章目录

一、简介

二、基本使用

  1. xml引用
  2. page布局
  3. 创建适配器
  4. 设置适配器
  5. 标题栏
    5.1. xml引用
    5.2. 重写PagerAdapter的getTitle()方法
  6. 翻页动画
    6.1. DepthPageTransformer
    6.2. ZoomOutPageTransformer
    6.3. 自定义动画
    6.4. 开源框架ViewPagerTransforms
  7. 翻页监听
    7.1. 设置方法
    7.2. 翻页监听接口
    7.3. 重写方法
    7.4. 使用

三、与Fragment结合使用

  1. 创建Fragment及相应的xml布局
  2. 给Viewpager设置数据和适配器

四、实现轮播图效果

  1. 特点
  2. 使用介绍
    2.1. 导包 + 权限
    2.2. xml引用
    2.3. 创建图片加载器
    2.4. 设置数据

五、实现画廊效果

  1. viewpager布局
  2. pager布局
  3. Adapter
  4. vp设置adapter
  5. 问题

项目学习资料整理分享链接:

Android高级进阶视频、源码、项目专题、面试真题解析免费分享​shimo.im

一、简介

Viewpager,视图翻页工具,提供了多页面切换的效果。Android 3.0后引入的一个UI控件,位于v4包中。低版本使用需要导入v4包,但是现在我们开发的APP一般不再兼容3.0及以下的系统版本,另外现在大多数使用Android studio进行开发,默认导入v7包,v7包含了v4,所以不用导包,越来越方便了。

Viewpager使用起来就是我们通过创建adapter给它填充多个view,左右滑动时,切换不同的view。Google官方是建议我们使用Fragment来填充ViewPager的,这样 可以更加方便的生成每个Page,以及管理每个Page的生命周期。

Viewpager在Android开发中使用频率还是比较高的,下面开始一起学习吧!

二、基本使用

1. xml引用

<android.support.v4.view.ViewPagerandroid:id="@+id/vp"android:layout_width="match_parent"android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

2. page布局

<?xml version="1.0" encoding="utf-8"?>
<TextViewandroid:id="@+id/tv"xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#FAE8DA"android:gravity="center"android:text="Hello"android:textSize="22sp">
</TextView>

3. 创建适配器

可直接new PagerAdapter,亦可创建它的子类

public class MyPagerAdapter extends PagerAdapter {private Context mContext;private List<String> mData;public MyPagerAdapter(Context context ,List<String> list) {mContext = context;mData = list;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object instantiateItem(ViewGroup container, int position) {View view = View.inflate(mContext, R.layout.item_base,null);TextView tv = (TextView) view.findViewById(R.id.tv);tv.setText(mData.get(position));container.addView(view);return view;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// super.destroyItem(container,position,object); 这一句要删除,否则报错container.removeView((View)object);}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}
}

4. 设置适配器

private void setVp() {List<String> list = new ArrayList<>();for (int i = 0; i < 3; i++) {list.add("第"+i+"个View");}ViewPager vp = (ViewPager) findViewById(R.id.vp);vp.setAdapter(new MyPagerAdapter(this,list));
}

效果:

5. 标题栏

给Viewpager设置标题栏有一下几种方式:

PagerTabStrip: 带有下划线
PagerTitleStrip: 不带下划线
TabLayout:5.0后推出
TabLayout的详细使用,可以看我的另一篇文章TabLayout。

下面介绍另外两个的使用方法,没什么区别:

1. xml引用

<android.support.v4.view.ViewPagerandroid:id="@+id/vp"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v4.view.PagerTitleStripandroid:id="@+id/pager_title"android:layout_width="match_parent"android:layout_height="45dp"android:background="@android:color/white"android:layout_gravity="top"android:textColor="#ff0000"android:textSize="18sp"></android.support.v4.view.PagerTitleStrip></android.support.v4.view.ViewPager><android.support.v4.view.ViewPagerandroid:id="@+id/vp"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v4.view.PagerTabStripandroid:id="@+id/pager_tab"android:layout_width="match_parent"android:layout_height="45dp"android:layout_gravity="top"android:background="@android:color/white"android:textColor="#ff0000"></android.support.v4.view.PagerTabStrip></android.support.v4.view.ViewPager>

  1. 重写PagerAdapter的getTitle()方法
@Override
public CharSequence getPageTitle(int position) {return mTitles[position];
}

这两种方法作为了解,不常用,项目中还没用到过

效果:

6. 翻页动画

ViewPager有个方法叫做:

setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 用于设置ViewPager切换时的动画效果,并且google官方还给出了两个示例(因为使用的是属性动画,所以不兼容3.0以下)。

1. DepthPageTransformer

public class DepthPageTransformer implements ViewPager.PageTransformer {private static final float MIN_SCALE = 0.75f;public void transformPage(View view, float position) {int pageWidth = view.getWidth();if (position < -1) { // [-Infinity,-1)// This page is way off-screen to the left.view.setAlpha(0);} else if (position <= 0) { // [-1,0]// Use the default slide transition when moving to the left pageview.setAlpha(1);view.setTranslationX(0);view.setScaleX(1);view.setScaleY(1);} else if (position <= 1) { // (0,1]// Fade the page out.view.setAlpha(1 - position);// Counteract the default slide transitionview.setTranslationX(pageWidth * -position);// Scale the page down (between MIN_SCALE and 1)float scaleFactor = MIN_SCALE+ (1 - MIN_SCALE) * (1 - Math.abs(position));view.setScaleX(scaleFactor);view.setScaleY(scaleFactor);} else { // (1,+Infinity]// This page is way off-screen to the right.view.setAlpha(0);}}
}

调用:

vp.setPageTransformer(false,new DepthPageTransformer());

效果:

2. ZoomOutPageTransformer

public class ZoomOutPageTransformer implements ViewPager.PageTransformer
{private static final float MIN_SCALE = 0.85f;private static final float MIN_ALPHA = 0.5f;@SuppressLint("NewApi")public void transformPage(View view, float position){int pageWidth = view.getWidth();int pageHeight = view.getHeight();Log.e("TAG", view + " , " + position + "");if (position < -1){ // [-Infinity,-1)// This page is way off-screen to the left.view.setAlpha(0);} else if (position <= 1) //a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0{ // [-1,1]// Modify the default slide transition to shrink the page as wellfloat scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));float vertMargin = pageHeight * (1 - scaleFactor) / 2;float horzMargin = pageWidth * (1 - scaleFactor) / 2;if (position < 0){view.setTranslationX(horzMargin - vertMargin / 2);} else{view.setTranslationX(-horzMargin + vertMargin / 2);}// Scale the page down (between MIN_SCALE and 1)view.setScaleX(scaleFactor);view.setScaleY(scaleFactor);// Fade the page relative to its size.view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE)/ (1 - MIN_SCALE) * (1 - MIN_ALPHA));} else{ // (1,+Infinity]// This page is way off-screen to the right.view.setAlpha(0);}}
}

调用:

vp.setPageTransformer(false,new ZoomOutPageTransformer());

效果:

3. 自定义动画
网上看到鸿洋大神写的

public class RotateDownPageTransformer implements ViewPager.PageTransformer {private static final float ROT_MAX = 20.0f;private float mRot;public void transformPage(View view, float position){Log.e("TAG", view + " , " + position + "");if (position < -1){ // [-Infinity,-1)// This page is way off-screen to the left.view.setRotation(0);} else if (position <= 1) // a页滑动至b页 ; a页从 0.0 ~ -1 ;b页从1 ~ 0.0{ // [-1,1]// Modify the default slide transition to shrink the page as wellif (position < 0){mRot = (ROT_MAX * position);view.setPivotX(view.getMeasuredWidth() * 0.5f);view.setPivotY(view.getMeasuredHeight());view.setRotation( mRot);} else{mRot = (ROT_MAX * position);view.setPivotX(view.getMeasuredWidth() * 0.5f);view.setPivotY(view.getMeasuredHeight());view.setRotation( mRot);}// Scale the page down (between MIN_SCALE and 1)// Fade the page relative to its size.} else{ // (1,+Infinity]// This page is way off-screen to the right.view.setRotation( 0);}}
}

效果:

position说明:
当前显示页为0,前一页为-1,后一页为1,滑动过程中数值不断变大或变小,所以为float类型

4. 开源框架ViewPagerTransforms
里面有十几种翻页动画,基本够用了
Github地址:ViewPagerTransforms

7. 翻页监听

1. 设置方法

addOnPageChangeListener()

2. 翻页监听接口

ViewPager.OnPageChangeListener

3. 重写方法
onPageScrolled(int position, float positionOffset, int positionOffsetPixels)

页面滑动状态停止前一直调用

position:当前点击滑动页面的位置
positionOffset:当前页面偏移的百分比
positionOffsetPixels:当前页面偏移的像素位置

onPageSelected(int position)

滑动后显示的页面和滑动前不同,调用

position:选中显示页面的位置

onPageScrollStateChanged(int state)

页面状态改变时调用

state:当前页面的状态

SCROLL_STATE_IDLE:空闲状态
SCROLL_STATE_DRAGGING:滑动状态
SCROLL_STATE_SETTLING:滑动后滑翔的状态

  1. 使用
vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {Log.e("vp","滑动中=====position:"+ position + "   positionOffset:"+ positionOffset + "   positionOffsetPixels:"+positionOffsetPixels);}@Overridepublic void onPageSelected(int position) {Log.e("vp","显示页改变=====postion:"+ position);}@Overridepublic void onPageScrollStateChanged(int state) {switch (state) {case ViewPager.SCROLL_STATE_IDLE:Log.e("vp","状态改变=====SCROLL_STATE_IDLE====静止状态");break;case ViewPager.SCROLL_STATE_DRAGGING:Log.e("vp","状态改变=====SCROLL_STATE_DRAGGING==滑动状态");break;case ViewPager.SCROLL_STATE_SETTLING:Log.e("vp","状态改变=====SCROLL_STATE_SETTLING==滑翔状态");break;}}
});

Log:

三、与Fragment结合使用

与Fragment结合使用其实也一样,只是用Fragment代替原先的View,填充Viewpager;然后就是Adapter不一样,配合Fragment使用的有两个Adapter:FragmentPagerAdapter和FragmentStatePagerAdapter。

相同点:
FragmentPagerAdapter和FragmentStatePagerAdapter都继承自PagerAdapter

不同点:
卸载不再需fragment时,各自采用的处理方法有所不同

FragmentStatePagerAdapter会销毁不需要的fragment。事务提交后, activity的FragmentManager中的fragment会被彻底移除。 FragmentStatePagerAdapter类名中的“state”表明:在销毁fragment时,可在onSaveInstanceState(Bundle)方法中保存fragment的Bundle信息。用户切换回来时,保存的实例状态可用来恢复生成新的fragment

FragmentPagerAdapter有不同的做法。对于不再需要的fragment, FragmentPagerAdapter会选择调用事务的detach(Fragment)方法来处理它,而非remove(Fragment)方法。也就是说, FragmentPagerAdapter只是销毁了fragment的视图, fragment实例还保留在FragmentManager中。因此,FragmentPagerAdapter创建的fragment永远不会被销毁

也就是:在destroyItem()方法中,FragmentStatePagerAdapter调用的是remove()方法,适用于页面较多的情况;FragmentPagerAdapter调用的是detach()方法,适用于页面较少的情况。但是有页面数据需要刷新的情况,不管是页面少还是多,还是要用FragmentStatePagerAdapter,否则页面会因为没有重建得不到刷新

使用如下:

1. 创建Fragment及相应的xml布局

public class PagerFragment extends Fragment {String mContent;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {mContent = (String) getArguments().get("content");View view = inflater.inflate(R.layout.fragment_pager, container, false) ;TextView textView = (TextView) view.findViewById(R.id.tv);textView.setText(mContent);return view;}}<FrameLayoutxmlns: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="com.strivestay.viewpagerdemo.PagerFragment"><TextViewandroid:id="@+id/tv"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:textSize="18sp"android:text="@string/hello_blank_fragment"/></FrameLayout>

2. 给Viewpager设置数据和适配器

private void setVp() {final List<PagerFragment> list = new ArrayList<>();for (int i = 0; i < 5; i++) {PagerFragment fragment = new PagerFragment();Bundle bundle = new Bundle();bundle.putString("content","第"+i+"个Fragment");fragment.setArguments(bundle);list.add(fragment);}ViewPager vp = (ViewPager) findViewById(R.id.vp);
//        vp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
//            @Override
//            public Fragment getItem(int position) {
//                return list.get(position);
//            }
//
//            @Override
//            public int getCount() {
//                return list.size();
//            }
//        });vp.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {@Overridepublic Fragment getItem(int position) {return list.get(position);}@Overridepublic int getCount() {return list.size();}});}

效果:

四、实现轮播图效果

这里我就不自己实现了,介绍一个轮播图开源控件:banner

1. 特点

支持无限循环和多种主题
可以灵活设置轮播样式、动画、轮播和切换时间、位置、图片加载框架

2. 使用介绍

1. 导包 + 权限

implementation 'com.youth.banner:banner:1.4.10'<!-- 加载网络图片需要权限 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 加载本地图片需要权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. xml引用

<com.youth.banner.Bannerandroid:id="@+id/banner"android:layout_width="match_parent"android:layout_height="自己设定"/>

3. 创建图片加载器

/*** 图片轮播加载*/
public class GlideImageLoader extends ImageLoader {@Override  // path随便传,我这里最终传的是个对象,拿到图片Urlpublic void displayImage(Context context, Object path, ImageView imageView) {//Glide 加载图片,Fresco也好、加载本地图片也好,这个类功能就是加载图片Glide.with(context).load(((AdList.DataBean)path).image).into(imageView);}
}

4. 设置数据

/*** 设置banner* @param data*/
private void setBanner(List<AdList.DataBean> data) {// banner样式banner.setBannerStyle(BannerConfig.NOT_INDICATOR);// 设置图片加载器banner.setImageLoader(new GlideImageLoader());// 设置图片集合banner.setImages(data);// 翻页特效banner.setBannerAnimation(Transformer.Default);// 设置轮播时间banner.setDelayTime(4000);// banner设置方法全部调用完毕时最后调用banner.start();
}@Override
public void onResume() {super.onResume();//开始自动翻页banner.startAutoPlay();
}@Override
public void onPause() {super.onPause();//停止翻页banner.stopAutoPlay();
}

以上是简单使用,更详细的用法可以直接到GitHub上去看,文档是中文的,很方便,API也很简单,上面已经给出链接

效果:(项目里截图不方便,直接拿的示例图)

五、实现画廊效果

效果如下:

实现步骤:1. viewpager布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:clipChildren="false"tools:context="com.strivestay.viewpagerdemo.FourthActivity"><include layout="@layout/layout_toolbar"/><android.support.v4.view.ViewPagerandroid:id="@+id/vp"android:layout_width="match_parent"android:layout_height="180dp"android:layout_marginTop="100dp"android:layout_marginLeft="30dp"android:layout_marginRight="30dp"android:clipChildren="false"></android.support.v4.view.ViewPager></LinearLayout>

要点:
给viewpager和它的父布局都设置属性android:clipChildren=“false”

. pager布局

item_banner_samll.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="200dp"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_banner"android:layout_width="200dp"android:layout_height="180dp"android:background="#009999"android:scaleType="centerCrop"/>
</LinearLayout>

item_banner.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageViewxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/iv_banner"android:layout_width="match_parent"android:layout_height="180dp"android:background="#009999"android:scaleType="centerCrop"/>

区别:
宽度,一个占满viewpager的宽度,一个小于viewpager的宽度

3. Adapter

/*** 画廊效果,page宽度占满vp* @author StriveStay* @date 2018/2/24*/
public class FourthPageAdapter extends PagerAdapter {private Context mContext;public FourthPageAdapter(Context context) {mContext = context;}@Overridepublic int getCount() {return Integer.MAX_VALUE;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {// 就4张图片position %= 4;View view = View.inflate(mContext,R.layout.item_banner,null);ImageView iv = (ImageView) view.findViewById(R.id.iv_banner);int resourceId = mContext.getResources().getIdentifier("img" + (position + 1), "drawable", mContext.getPackageName());Glide.with(mContext).load(resourceId).into(iv);//            iv.setImageResource(resourceId);container.addView(view);return view;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View)object);}}

如果是page宽度 < vp宽度,需要重写getPageWidth()方法,用于计算page占据vp的百分比

@Override
public float getPageWidth(int position) {float itemWidth =  (mContext.getResources().getDisplayMetrics().density * 200);float vpWidth = (mContext.getResources().getDisplayMetrics().widthPixels - mContext.getResources().getDisplayMetrics().density * 60);return  itemWidth / vpWidth;
}

3. vp设置adapter

private void setVp() {ViewPager vp = (ViewPager) findViewById(R.id.vp);// 设置适配器
//        vp.setAdapter(new FourthPageAdapter(this));vp.setAdapter(new FourthSmallPageAdapter(this));// page 边距vp.setPageMargin((int)(getResources().getDisplayMetrics().density * 15));// 为了左右无限滑动,显示在中间,且显示第一张int i = Integer.MAX_VALUE/2%4;vp.setCurrentItem(Integer.MAX_VALUE/2 + (4-i));}

4. 问题
当page宽度 < vp宽度,且page的数量较少,没有占满vp,这时滑动vp,会出现闪屏,如下:

解决办法:

当明确知道vp放不下2个page时,可以如下处理

@Override
public float getPageWidth(int position) {// 加上这句if(getCount() < 2){return super.getPageWidth(position);}float itemWidth =  (mContext.getResources().getDisplayMetrics().density * 200);float vpWidth = (mContext.getResources().getDisplayMetrics().widthPixels - mContext.getResources().getDisplayMetrics().density * 60);Log.e("比例",vpWidth+"==="+itemWidth+"==="+(int)(vpWidth/itemWidth));return  itemWidth / vpWidth;}

当vp可以放置两个以上的page时,也是个通用的方法

vp.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// vp中最多能放下2个page,则让vp中page个数 < 3时,让vp不能滑动if(vp.getChildCount() < 3 && event.getAction() == MotionEvent.ACTION_MOVE){return true;}return false;}
});

原文链接:https://blog.csdn.net/weixin_39251617/article/details/79399592

更多Android高级架构进阶视频学习请点击:

哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibili​links.jianshu.com

Android高级架构学习资料整理分享链接:

Android高级进阶视频、源码、项目专题、面试真题解析免费分享​shimo.im

原文链接:https://blog.csdn.net/weixin_39251617/article/details/79399592

container view_高级UI晋升之常用View(三)中篇相关推荐

  1. 调用某个按钮事件_高级UI晋升之触摸事件分发机制(一)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 0. 前言 鉴于安卓分发机制较为复杂,故分为多个层次进行讲解,分别为基础篇.实践 ...

  2. 你连《Android高级UI与FrameWork源码》都搞不懂学什么Android?还敢面试阿里P7!

    Android高级UI与FrameWork源码 重要性? 这块知识是现今使用者最多的,我们称之为Android2013~2016年的技术,但是,即使是这样的技术,Android开发者也往往因为网上Co ...

  3. Android 高级UI解密 (三) :Canvas裁剪 与 二维、三维Camera几何变换(图层Layer原理)

    Android的绘图机制是核心内容之一,无论是什么样的功能最终都是以图像的形式呈现给用户.因此掌握Android的绘图技巧,有助于Android理解层次的提高,在面对产品经理提出的idea时也更有底气 ...

  4. Android 高级UI解密 (四) :花式玩转贝塞尔曲线(波浪、轨迹变换动画)

    讲解此UI系列必然少不了一个奇妙数学曲线-–贝塞尔曲线,它目前运用于App的范围是在太广了,最初的QQ气泡拖拽,到个人界面的波浪效果.Loading波浪效果,甚至于轨迹变化的动画都可以依赖贝塞尔曲线完 ...

  5. android炫酷动画代码,Android高级UI特效仿直播点赞动画效果

    Android高级UI特效仿直播点赞动画效果 发布时间:2020-10-02 16:06:18 来源:脚本之家 阅读:117 作者:mrr 本文给大家分享高级UI特效仿直播点赞效果-一个优美炫酷的点赞 ...

  6. android scroller,高级UI第四十四篇:Android Scroller详解

    滚动视图的方法有两种:scrollTo和scrollBy,而Scroller就是它们的辅助工具类,所以Scroller是学好高级UI必不可少的一课. (1)scrollTo.scrollBy.getS ...

  7. Android高级UI系列教程(二)

    上期回顾 Android高级UI系列教程(一)_我想月薪过万的博客-CSDN博客https://blog.csdn.net/qq_41885673/article/details/121870917 ...

  8. 从初级晋级高级UI设计师学习路线+全套视频

    不管是零基础小白,还是已经入行学设计的年轻人,在学习UI的路上,难免深受这些难题的困扰: ◆ 如何才能成功进攻UI行业呢? ◆ 零基础怎样学习才能更快入门.学起来更有效率? ◆ 怎么确保自己学到的是市 ...

  9. 广州优漫动游公司:高级UI/UE交互设计就业班学什么?

    广州ui设计培训学校,UI交互设计培训,ui界面设计培训,UI培训学校,ui界面交互设计培训,UI培训哪个学校好–高级UI交互设计就业班.UI设计培训,高级UI/UE交互设计就业班. 一.培训特色 项 ...

最新文章

  1. 涨姿势,Java中New一个对象是个怎么样的过程?
  2. 卡巴斯基工业基础设施专用网络安全解决方案
  3. 用电线来传网络信号的黑科技?AirGig究竟是什么
  4. 支付系统高可用架构设计实战,可用性高达99.999!
  5. github使用ssh key
  6. jconsole查看连接数_在JConsole和VisualVM中查看DiagnosticCommandMBean
  7. 社区架构培训班四期开始报名了
  8. matlab去趋势,[转载]使用Matlab对数据进行去趋势(detrend)
  9. CYQ.Data 轻量数据层之路 V3.0版本发布-Xml绝对杀手(三十二)
  10. 复习zabbix配置agent过程
  11. 常用的织梦(dedecms)调用标签
  12. 租房管理系统毕业设计Java_java毕业设计_springboot框架的租房管理系统
  13. Xcode调试技巧总结
  14. 虹科案例|基于SOLA光源的高通量Spike展示平台加速新冠病毒疫苗研制
  15. Photoshop:PS如何实现放大图片不模糊
  16. 我的markdown
  17. 【总结】线性代数的本质 - 3
  18. AngularJS 模型
  19. nyoj 1273 宣传墙
  20. 前端导出后端文件的方法

热门文章

  1. [ES6] 细化ES6之 -- 前端模块化
  2. JS 异步编程及常考面试题
  3. JavaScript算法(实例八)递归计算每个月的兔子总数【斐波那契数列】
  4. Tips--更改Jupyter Notebook的默认工作路径
  5. MTCNN-tensorflow源码解析-gen_landmark_aug_12.py;gen_imglist_pnet.py
  6. CNN经典模型:VGGNet
  7. PTA20、字典合并 (10 分)
  8. java ee无法安装_为什么要导入javax.servlet。*; 安装Java EE仍无法解决 面向Java EE开发人员的Eclipse...
  9. php 价格计算方法,PHP算法逻辑:如何计算购买量?
  10. sql server 存储过程的详解