更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680
本篇文章将从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. 问题

一、简介

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.ViewPager
android: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"?>
<TextView
android: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;
} @Override
public int getCount() {
return mData.size();
} @Override
public 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;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container,position,object); 这一句要删除,否则报错
container.removeView((View)object);
} @Override
public 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));
}

效果:

 
20180228134517956.gif

5. 标题栏

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

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

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

1. xml引用

<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v4.view.PagerTitleStrip
android: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.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v4.view.PagerTabStrip
android: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 page
view.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 transition
view.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 well
float 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 well
if (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() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.e("vp","滑动中=====position:"+ position + " positionOffset:"+ positionOffset + " positionOffsetPixels:"+positionOffsetPixels);
} @Override
public void onPageSelected(int position) {
Log.e("vp","显示页改变=====postion:"+ position);
} @Override
public 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; @Override
public 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;
} }

<FrameLayout
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="com.strivestay.viewpagerdemo.PagerFragment"> <TextView
android: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()) {
@Override
public Fragment getItem(int position) {
return list.get(position);
} @Override
public 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.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="自己设定"/>

3. 创建图片加载器

/**
* 图片轮播加载
*/
public class GlideImageLoader extends ImageLoader { @Override // path随便传,我这里最终传的是个对象,拿到图片Url
public 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"?>
<LinearLayout
xmlns: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.ViewPager
android: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"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical"> <ImageView
android: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"?>
<ImageView
xmlns: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;
} @Override
public int getCount() {
return Integer.MAX_VALUE;
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public 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;
} @Override
public 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() {
@Override
public 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;
}
});

更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680
原文链接:https://blog.csdn.net/weixin_39251617/article/details/79399592

高级UI晋升之常用View(三)中篇的更多相关文章

  1. 高级UI晋升之常用View(三)下篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从WebView来介绍常用View: 一.WebView介绍 Andro ...

  2. 高级UI晋升之常用View(三)上篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下两个内容来介绍常用View: [RecycleView] [Ca ...

  3. 高级UI晋升之自定义View实战(五)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从自定义View利器Canvas和Paint来进行详解 一.Canvas ...

  4. 高级UI晋升之自定义view实战(七)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义ViewGroup实现瀑布流效果来进行详解dispatchTouch ...

  5. 高级UI晋升之自定义View实战(六)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从Android 自定义属性动画&Camera动画来介绍自定义V ...

  6. 高级UI晋升之自定义View实战(九)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 1.前言: 本文采用自定义view的方法来实现一键清除的动画这个功能. 2.效果 ...

  7. 高级UI晋升之自定义View实战(八)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义流式布局来进行介绍: 一般常见的流式布局由两种,一种是横向的个数固定 ...

  8. 高级UI晋升之布局ViewGroup(四)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从LinearLayout.RelativeLayout.FrameLa ...

  9. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

随机推荐

  1. vue-cesium中经纬度写反了,报错

    vue-cesium中经纬度写反了,报错 [Vue warn]: Invalid prop: custom validator check failed for prop "position ...

  2. Cocos2d-x 发布 Android

    Cocos2d-x 发布 Android 前置需求: Android NDK Android SDK OR Eclipse ADT Bundle Android AVD target installe ...

  3. axios interceptors 拦截 , 页面跳转, token 验证 Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示)

    Vue+axios实现登陆拦截,axios封装(报错,鉴权,跳转,拦截,提示) :https://blog.csdn.net/H1069495874/article/details/80057107 ...

  4. CSS实现进度条

    进度条经常运用于网页,即使我们意识到不是所有的东西都将瞬间被加载完成,这些进度条用于提醒使用者关于网页上具体的任务进程,譬如上传,下载,加载应用程序等. 以前如果想要创建一个进度条的动画效果,没有使用 ...

  5. 数据库全表扫描的SQL种类

    1.所查询的表的条件列没有索引: 2.需要返回所有的行: 3.对索引主列有条件限制,但是使用了函数,则Oracle 使用全表扫描,如: where  upper(city)=’TOKYO’; 这样的语 ...

  6. elasticsearch-6.0.1安装

    elasticsearch-6.0.1安装 0. 介绍:     ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎:是目前全文搜索引擎的首选. ...

  7. SQL必知必会——思维导图

    Xmind实在太坑了,竟然不能导出高清图片,我回来折腾个PS整一下!

  8. SQL Server 2014 中新建登录及权限分配【界面版】

    本篇经验将和大家介绍分配SQL Server 2014 中,新建登录用户,分配权限,并指定该用户的数据库的方法,希望对大家的工作和学习有所帮助! 方法/步骤 1 打开 MS SQL Server Ma ...

  9. 初探Remoting双向通信(二)

    原 初探Remoting双向通信(二) 2013年06月25日 11:46:24 喜欢特别冷的冬天下着雪 阅读数 2977 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...

  10. 学习JS基本数据类型与对象的valueOf方法

    https://blog.csdn.net/licheng11403080324/article/details/60128090 https://yq.aliyun.com/articles/399 ...