TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
使用TabLayout搭配ViewPager实现可滑动的顶部选项卡效果。
效果图
代码分析
1、演示常规的设置。
2、通过自定义ViewPager(MyCustomViewPager)解决解决切换需要经过中间页的问题、实现控制viewpager是否可滑动的功能;
3.1、通过在Fragment中的OnCreateView中判断rootView是否为空来解决viewpager+fragment来回滑动fragment重新加载的问题;
3.2、还有一个方案是在自定义的viewpager适配器类中重写destroyItem方法,来解决重新加载的问题;【核心就是不销毁fragment】
4、通过自定义Fragment基类(BaseLazyFragment)来实现配合viewpager使用时禁止懒加载的功能;
存在一个问题:那就是当选项卡比较多的时候,从首页切换到尾页,然后切换回来首页的时候,会重新请求数据,因为首页已经销毁了,执行了onDestroyView方法。
解决方案:
一、使用setOffscreenPageLimit()方法, 设置数字越大越好(可以设置总数目);
二、采用3.2方案;
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
引入依赖库
在APP的build.gradle文件中添加以下代码【注意:版本号和com.android.support:appcompat-v7保持一致】
注意:TabLayout为5.0之后的新控件,所以styles.xml中的主题应该使用Theme.AppCompat.Light.NoActionBar或者Theme.AppCompat.Light等Theme.AppCompat.XXX的主题
apply plugin: 'com.android.application' android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.why.project.tablayoutviewpagerdemo"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//TabLayout
compile 'com.android.support:design:25.3.1'
}
在colors.xml文件中添加以下代码:【后续可根据实际情况更改背景颜色、文字颜色值】
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color> <!-- *********************************顶部选项卡区域********************************* -->
<!-- 顶部选项卡下划线背景色 -->
<color name="tab_auto_normal_top">#00ffffff</color>
<color name="tab_auto_selected_top">#3090d9</color>
<!-- 顶部选项卡文本颜色 -->
<color name="tab_text_normal_top">#191919</color>
<color name="tab_text_selected_top">#3090d9</color>
</resources>
在dimens.xml文件中添加以下代码:【后续可根据实际情况更改底部选项卡区域的高度值、文字大小值】
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen> <!-- *********************************顶部选项卡区域********************************* -->
<!-- 选项卡的内边距 -->
<dimen name="tab_top_auto_padding">10dp</dimen>
<!-- 选项卡标题的文字大小 -->
<dimen name="tab_top_auto_title_size">18sp</dimen>
<!-- 选项卡标题的下划线高度 -->
<dimen name="tab_top_auto_height">3dp</dimen>
</resources>
在styles.xml文件中添加以下代码:
<resources> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> <!-- TabLayout的文字大小 -->
<style name="TabLayoutTextStyle">
<item name="android:textSize">@dimen/tab_top_auto_title_size</item>
</style> </resources>
在AndroidManifest.xml文件中添加网络请求的权限【demo中用到的】
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.tablayoutviewpagerdemo"> <!-- ======================授权访问网络(HttpUtil)========================== -->
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET"/> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>
三、使用方法
在Activity布局文件中引用TabLayout【注意更改MyViewpager的完整路径】
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.why.project.tablayoutviewpagerdemo.MainActivity"> <!-- 选项卡区域 -->
<!--设置TabLayout的模式 app:tabMode 默认是fixed:固定的,标签很多时候会被挤压,不能滑动。-->
<!--设置整个TabLayout的颜色 app:tabBackground-->
<!--设置选中字体的颜色 app:tabSelectedTextColor-->
<!--设置未选中字体的颜色 app:tabTextColor-->
<!--设置指示器下标的颜色 app:tabIndicatorColor-->
<!--设置指示器下标的高度 app:tabIndicatorHeight,如果设置的是0.0dp,则代表没有下划线-->
<!--设置内容的显示模式 app:tabGravity,center : 居中,如果是fill,则是充满-->
<android.support.design.widget.TabLayout
android:id="@+id/tl_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@android:color/transparent"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/tab_text_selected_top"
app:tabTextColor="@color/tab_text_normal_top"
app:tabTextAppearance="@style/TabLayoutTextStyle"
app:tabIndicatorColor="@color/tab_auto_selected_top"
app:tabIndicatorHeight="@dimen/tab_top_auto_height"
app:tabGravity="center"
/> <!-- viewpager区域 -->
<com.why.project.tablayoutviewpagerdemo.viewpager.MyCustomViewPager
android:id="@+id/vp_tab"
android:layout_width="match_parent"
android:layout_height="0.0dp"
android:layout_weight="1"/> </LinearLayout>
创建需要用到的fragment类和布局文件【后续可根据实际情况更改命名,并且需要重新import R文件】
fragment_web.xml文件布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!-- webview -->
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></WebView> </LinearLayout>
WebViewFragment
package com.why.project.tablayoutviewpagerdemo.fragment; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient; import com.why.project.tablayoutviewpagerdemo.R; /**
* @Created HaiyuKing
* @Used 首页界面——碎片界面
*/
public class WebViewFragment extends BaseLazyFragment{ private static final String TAG = "WebViewFragment";
/**View实例*/
private View myView; private WebView web_view; /**传递过来的参数*/
private String bundle_param; //重写
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { //使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态。
//http://www.cnblogs.com/changkai244/p/4110173.html
if(myView == null){
myView = inflater.inflate(R.layout.fragment_web, container, false);
//接收传参
Bundle bundle = this.getArguments();
bundle_param = bundle.getString("param");
}
//缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) myView.getParent();
if (parent != null) {
parent.removeView(myView);
} return myView;
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
//初始化控件以及设置
initView();
//初始化控件的点击事件
initEvent(); // TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
} //实现禁止预加载的功能
@Override
public void fetchData() {
//初始化数据
initData();
}
//实现禁止预加载的功能
@Override
public void onInvisible() { } @Override
public void onResume() {
super.onResume();
} @Override
public void onPause() {
super.onPause();
} @Override
public void onDestroy() {
super.onDestroy();
} /**
* 初始化控件
*/
private void initView() {
web_view = (WebView) myView.findViewById(R.id.web_view);
//设置支持js脚本
// web_view.getSettings().setJavaScriptEnabled(true);
web_view.setWebViewClient(new WebViewClient() {
/**
* 重写此方法表明点击网页内的链接由自己处理,而不是新开Android的系统browser中响应该链接。
*/
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
//webView.loadUrl(url);
return false;
}
});
} /**
* 初始化数据
*/
public void initData() {
Log.e("tag","{initData}bundle_param="+bundle_param);
web_view.loadUrl(bundle_param);//加载网页
} /**
* 初始化点击事件
* */
private void initEvent(){
} }
BaseLazyFragment
package com.why.project.tablayoutviewpagerdemo.fragment; import android.os.Bundle;
import android.util.Log; /**
* Used 主要实现配合viewpager使用时禁止懒加载
* 我们一般在onCreateView方法初始化视图,onActivityCreated方法初始化数据,
* 通过setUserVisibleHint和getUserVisibleHint方法来设置和获取Fragment的显示状态,当显示了才去加载数据。
*
* setUserVisibleHint: isVisibleToUser = false
onAttach
onCreate
setUserVisibleHint: isVisibleToUser = true
onCreateView
onActivityCreated
onStart
onResume
onPause
onStop
onDestroyView
onDestroy
onDetach
参考资料:https://blog.csdn.net/aiynmimi/article/details/73277836 */ public abstract class BaseLazyFragment extends BaseFragment{ private static final String TAG = BaseLazyFragment.class.getSimpleName(); /**
* rootView是否初始化标志,防止回调函数在rootView为空的时候触发
*/
protected boolean isViewInitiated;//view是否初始化
/**
* 当前Fragment是否处于可见状态标志,防止因ViewPager的缓存机制而导致回调函数的触发
*/
protected boolean isVisibleToUser;//是否可见
protected boolean isDataInitiated;//数据是否加载完成 @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.e(TAG,"{setUserVisibleHint}isVisibleToUser="+isVisibleToUser);
super.setUserVisibleHint(isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
if(getUserVisibleHint()) {
prepareFetchData();
} else {
if(isViewInitiated){
onInvisible();
}
}
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isViewInitiated = true;
prepareFetchData();
} /**
* 视图销毁的时候 Fragment是否初始化的状态变为false
*/
@Override
public void onDestroyView() {
Log.e(TAG,"{onDestroyView}");
super.onDestroyView();
isViewInitiated = false;
isVisibleToUser = false;
isDataInitiated = false;
} //初始化数据
public abstract void fetchData();
//当隐藏的时候执行的方法
public abstract void onInvisible(); public boolean prepareFetchData() {
return prepareFetchData(false);
} /**
* 请求数据
* @param forceUpdate : 是否强制请求数据*/
public boolean prepareFetchData(boolean forceUpdate) {
if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
fetchData();
isDataInitiated = true;
return true;
}
return false;
}
}
BaseLazyFragment.java
创建选项卡子项model类TabItemModel
package com.why.project.tablayoutviewpagerdemo.model; /**
* Created by HaiyuKing
* Used
*/ public class TabItemModel {
private String tabTitle;
private String tabUrl; public TabItemModel(String tabTitle, String tabUrl){
this.tabTitle = tabTitle;
this.tabUrl = tabUrl;
} public String getTabTitle() {
return tabTitle;
} public void setTabTitle(String tabTitle) {
this.tabTitle = tabTitle;
} public String getTabUrl() {
return tabUrl;
} public void setTabUrl(String tabUrl) {
this.tabUrl = tabUrl;
}
}
创建viewpager的适配器
package com.why.project.tablayoutviewpagerdemo.adapter; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup; import com.why.project.tablayoutviewpagerdemo.model.TabItemModel; import java.util.List; /**
* Created by HaiyuKing
* Used 当viewpager中fragment数量多的时候用FragmentStatePagerAdapter,反之则用FragmentPagerAdapter。
*/ public class ContentPagerAdapter extends FragmentStatePagerAdapter { private List<TabItemModel> tabIndicators;
/**碎片集合*/
private List<Fragment> fragmentList; public ContentPagerAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
} /**
* 自定义构造函数:用于传递碎片集合过来
* 一般都写上*/
public ContentPagerAdapter(FragmentManager fm, List<TabItemModel> tabIndicators, List<Fragment> fragmentList) {
super(fm);
this.tabIndicators = tabIndicators;
this.fragmentList = fragmentList;
} @Override
public Fragment getItem(int position) {
return fragmentList.get(position);
} @Override
public int getCount() {
return fragmentList.size();
} @Override
public CharSequence getPageTitle(int position) {
return tabIndicators.get(position).getTabTitle();
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
//viewpager+fragment来回滑动fragment重新加载的简单解决办法:注释下面的代码
//不建议使用,因为当选项卡过多的时候,如果不销毁的是,担心内存溢出
//http://blog.csdn.net/qq_28058443/article/details/51519663
super.destroyItem(container, position, object);
}
}
MyCustomViewPager
package com.why.project.tablayoutviewpagerdemo.viewpager; import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; /**
* Created by HaiyuKing
* Used 自定义的viewpager
* https://www.cnblogs.com/tangs/articles/5933233.html
* 解决切换需要经过中间页的问题;
* 实现控制viewpager是否可滑动;
* 解决视频播放器和viewpager滑动冲突问题【可扩展到任何view】;
*/ public class MyCustomViewPager extends ViewPager { /**是否可以滑动:默认可以滑动*/
private boolean isCanScroll = true; public MyCustomViewPager(Context context) {
super(context);
} public MyCustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
} /**
* 解决切换需要经过中间页
*/
@Override
public void setCurrentItem(int item) {
//super.setCurrentItem(item);源码
super.setCurrentItem(item,false);//smoothScroll false表示切换的时候,不经过两个页面的中间页
} /**
* 让ViewPager不能左右滑动
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(isCanScroll){
return super.onTouchEvent(ev);
}else{
return false;
}
} @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(isCanScroll){
return super.onInterceptTouchEvent(ev);
}else{
return false;
}
} /**
* 暴露出去的方法,屏蔽ViewPager的滑动,默认不可滑动
* @param isCanScroll 为true可以左右滑动,为false不可滑动
*/
public void setIsCanScroll(boolean isCanScroll){
this.isCanScroll = isCanScroll;
} @Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { /*if (v instanceof IjkVideoView) {//解决视频播放器和viewpager滑动冲突问题
return true;
}*/
return super.canScroll(v, checkV, dx, x, y);
}
}
MyCustomViewPager.java
在Activity中使用如下【继承FragmentActivity或者其子类】
package com.why.project.tablayoutviewpagerdemo; import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity; import com.why.project.tablayoutviewpagerdemo.adapter.ContentPagerAdapter;
import com.why.project.tablayoutviewpagerdemo.fragment.WebViewFragment;
import com.why.project.tablayoutviewpagerdemo.model.TabItemModel;
import com.why.project.tablayoutviewpagerdemo.viewpager.MyCustomViewPager; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity { private TabLayout mTabLayout;
private MyCustomViewPager mTabViewPager; private List<TabItemModel> tabIndicators;
private List<Fragment> tabFragments; private ContentPagerAdapter contentAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents(); } private void initViews() {
mTabLayout = (TabLayout) findViewById(R.id.tl_top);
mTabViewPager = (MyCustomViewPager) findViewById(R.id.vp_tab);
mTabViewPager.setOffscreenPageLimit(3);//禁止预加载【如果想要延迟首个选项卡的销毁时间,那么就需要设置这个数值高点】
} private void initDatas() {
//初始化选项卡子项的文本、超链接model集合
tabIndicators = new ArrayList<TabItemModel>();
tabIndicators.add(new TabItemModel("百度","http://www.baidu.com"));
tabIndicators.add(new TabItemModel("CSDN","http://blog.csdn.net"));
tabIndicators.add(new TabItemModel("博客园","http://www.cnblogs.com"));
tabIndicators.add(new TabItemModel("极客头条","http://geek.csdn.net/mobile"));
tabIndicators.add(new TabItemModel("优设","http://www.uisdc.com/"));
tabIndicators.add(new TabItemModel("玩Android","http://www.wanandroid.com/index"));
tabIndicators.add(new TabItemModel("掘金","https://juejin.im/")); //初始化碎片集合
tabFragments = new ArrayList<>(); for(int i=0;i<tabIndicators.size();i++){
TabItemModel tabItemModel = tabIndicators.get(i); Bundle bundle = new Bundle();
bundle.putString("param", tabItemModel.getTabUrl());
tabFragments.add(WebViewFragment.getInstance(WebViewFragment.class,bundle));
}
//实例化Adapter
contentAdapter = new ContentPagerAdapter(getSupportFragmentManager(),tabIndicators,tabFragments);
mTabViewPager.setAdapter(contentAdapter);
//TabLayout和ViewPager相关联
mTabLayout.setupWithViewPager(mTabViewPager);
} private void initEvents() {
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//选中了tab的逻辑
} @Override
public void onTabUnselected(TabLayout.Tab tab) {
//未选中了tab的逻辑
} @Override
public void onTabReselected(TabLayout.Tab tab) {
//再次选中了tab的逻辑
}
});
}
}
混淆配置
无
参考资料
Android TabLayout 分分钟打造一个滑动标签页
【Android】Fragment懒加载和ViewPager的坑
TabLayout-ViewPager填充Fragment和懒加载
ViewPager+Fragment LazyLoad懒加载最优解
Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案
viewPaper+Fragment的布局,在初始化时会导致fragment的布局加载和网络请求数据(懒加载)
项目demo下载地址
https://github.com/haiyuKing/TabLayoutViewPagerDemo
TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】的更多相关文章
- Android TabLayout+ViewPager禁止滑动
1.重写ViewPager并重写覆盖ViewPager的onInterceptTouchEvent(MotionEvent arg0)方法和onTouchEvent(MotionEvent arg0) ...
- 关于TabLayout+ViewPager组合实现多页面滑动
转载请注明出处:http://blog.csdn.net/ht_android/article/details/46647711 在android提供的design library中新增了一个控件,叫 ...
- 011 Android TabLayout+ViewPager实现顶部滑动效果(多个页面)
1.TabLayout介绍 TabLayout提供了一个水平的布局用来展示Tabs,很多应用都有这样的设计,典型的有网易新闻,简书,知乎等.TabLayout就可以很好的完成这一职责,首先TabLay ...
- 浅谈TabLayout(ViewPager+Tab联动)
google发布了的Android Support Design库中提供了TabLayout 通过TabLayout+ViewPager实现导航栏效果,点击Tab ,ViewPager跟随变化,滑动V ...
- 介绍三个Android支持库控件:TabLayout+ViewPager+RecyclerView
本文主要介绍如下三个Android支持库控件的配合使用: TabLayout:android.support.design.widget.TabLayout ViewPager:android.sup ...
- Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- ViewPagerWithRecyclerDemo【RecyclerView+ViewPager实现类似TabLayout+ViewPager效果】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用RecyclerView+ViewPager实现类似TabLayout+ViewPager效果. 效果图 使用步骤 一.项目组织 ...
- 安卓TabLayout+ViewPager实现切页
安卓使用TabLayout+ViewPager+Fragment 实现页面切换,可实现左右滑动切换视图界面和点击切换 可自定义菜单栏是在顶部还是在底部 一.实现效果: 二.实现过程: 2.1 一些重要 ...
- TabLayout + ViewPager
一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0'compile 'com.android. ...
随机推荐
- Juint单元测试
********************************************************************************************* 单元测试:集 ...
- (2)STM32使用HAL库操作外部中断——理论讲解
1.中断触发过程 对主程序压栈--把中断服务函数的地址写入到程序计数器(PC)--执行中断服务函数 2.中断向量表 中断服务函数的地址在STM32的手册上的中断向量表中(如下是一部分): 如上表所示, ...
- 关于table表格 td里内容较多换行的处理方法
最近在用table的时候由于td内容较多默认换行了,很不美观.于是找到处理方法: 在声明table的时候添加一个样式: <table id="tbOffice" data-r ...
- maven创建web报错Cannot read lifecycle mapping metadata for artifact org.apache.maven.plugins:maven-compiler-plugin:maven-compiler-plugin:3.5.1:runtime Cause: error in opening zip file
Cannot read lifecycle mapping metadata for artifact org.apache.maven.plugins:maven-compiler-plugin:m ...
- 使用Akka的远程调用
概述 正如其它RPC或者RMI框架那样,Akka也提供了远程调用的能力.服务端在监听的端口上接收客户端的调用.本文将在<Spring与Akka的集成>一文的基础上介绍Akka的remote ...
- 浅谈surging服务引擎中的rabbitmq组件和容器化部署
1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...
- 安卓开发笔记(二十八):仿写IOS switch选择器控件实现,checkbox
我们先来看看效果: 这里我们主要使用了github上的一个开源项目,配置起来比较方便,下面解释一下该如何使用:首先是:Gradle文件当中进行配置: dependencies { implementa ...
- 每日分享!JavaScript的鼠标事件(11个事件)
鼠标的11个事件 具体的事件解释如下: click:按下鼠标(通常是按下主按钮)时触发. dblclick:在同一个元素上双击鼠标时触发. mousedown:按下鼠标键时触发. mouseup:释放 ...
- 从壹开始微服务 [ DDD ] 之十二 ║ 核心篇【下】:事件驱动EDA 详解
缘起 哈喽大家好,又是周二了,时间很快,我的第二个系列DDD领域驱动设计讲解已经接近尾声了,除了今天的时间驱动EDA(也有可能是两篇),然后就是下一篇的事件回溯,就剩下最后的权限验证了,然后就完结了, ...
- asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)
一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...