Android的UI设计可以说是决定一个app质量的关键因素,因为人们在使用app的时候,最先映入眼帘的就是app的界面了,一个美观、充实的界面能够给用户带来非常好的体验,会在用户心中留下好的印象。

对于UI设计,Android原生的控件加上一些开源库的使用,已经能够满足大部分的UI需求,但是,某些比较新颖、花哨的控件效果,我们只能通过自定义View来实现,那么,从该篇博客开始,我将记录关于Android自定义View的学习内容,并将其整理呈现给大家。


我们来实现一个优酷菜单案例,在案例中会涉及到很多方面的知识。

案例效果如下:



对activity_main.xml文件进行修改。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.itcast.youkumenu.MainActivity"> <RelativeLayout
android:id="@+id/level1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1">
</RelativeLayout> <RelativeLayout
android:id="@+id/level2"
android:layout_width="180dp"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2">
</RelativeLayout> <RelativeLayout
android:id="@+id/level3"
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level3">
</RelativeLayout> </RelativeLayout>

预览一下效果。



貌似效果已经出来了,但是请注意了,我这样布局的话能点到每个圆环吗?看上面的图片,我只能点到蓝色线条框住的矩形,这是因为小圆环被大圆环覆盖了,我们重新修改一下布局代码。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.itcast.youkumenu.MainActivity"> <RelativeLayout
android:id="@+id/level3"
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level3">
</RelativeLayout> <RelativeLayout
android:id="@+id/level2"
android:layout_width="180dp"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2">
</RelativeLayout> <RelativeLayout
android:id="@+id/level1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1">
</RelativeLayout> </RelativeLayout>

此时预览一下。



我已经能正确点击到每一个圆环,而我的代码只是将三个相对布局调换了一下位置,既然大圆环会覆盖到小圆环,那我们直接把大圆环放到最上面,这样就不会出现覆盖问题了。

这是我们需要注意的一个点。接下来贴出完整的布局代码。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.itcast.youkumenu.MainActivity"> <RelativeLayout
android:id="@+id/level3"
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level3"> <ImageView
android:id="@+id/channel1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:src="@drawable/channel1" /> <ImageView
android:id="@+id/channel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel1"
android:layout_marginBottom="8dp"
android:layout_marginLeft="33dp"
android:src="@drawable/channel2" /> <ImageView
android:id="@+id/channel3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel2"
android:layout_marginBottom="8dp"
android:layout_marginLeft="63dp"
android:src="@drawable/channel3" /> <ImageView
android:id="@+id/channel4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:src="@drawable/channel4" /> <ImageView
android:id="@+id/channel7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="8dp"
android:src="@drawable/channel7" /> <ImageView
android:id="@+id/channel6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel7"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="33dp"
android:src="@drawable/channel6" /> <ImageView
android:id="@+id/channel5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel6"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="63dp"
android:src="@drawable/channel5" />
</RelativeLayout> <RelativeLayout
android:id="@+id/level2"
android:layout_width="180dp"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:src="@drawable/icon_search" /> <ImageView
android:id="@+id/icon_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:src="@drawable/icon_menu" /> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="8dp"
android:layout_marginRight="8dp"
android:src="@drawable/icon_myyouku" />
</RelativeLayout> <RelativeLayout
android:id="@+id/level1"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1"> <ImageView
android:id="@+id/icon_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/icon_home" />
</RelativeLayout> </RelativeLayout>

这样布局我们就完成了,接下来我们要实现功能了。

我们可以把功能分为两层,我们先完成中间圆环菜单键控制最外层圆环旋转的动画。然后再完成最里层圆环home键控制中间圆环旋转的动画。

修改MainActivity的代码。

package com.itcast.youkumenu;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast; public class MainActivity extends AppCompatActivity { private RelativeLayout level1;
private RelativeLayout level2;
private RelativeLayout level3;
private ImageView icon_menu;
private ImageView icon_home; /**
* 是否显示最外层圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel3 = true; /**
* 是否显示中间圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel2 = true; /**
* 是否显示最里层圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel1 = true; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); } private void initView() {
level3 = (RelativeLayout) findViewById(R.id.level3);
icon_menu = (ImageView) findViewById(R.id.icon_menu);
level2 = (RelativeLayout) findViewById(R.id.level2);
icon_home = (ImageView) findViewById(R.id.icon_home);
level1 = (RelativeLayout) findViewById(R.id.level1); MyOnClickListener myOnClickListener = new MyOnClickListener();
//设置点击事件
icon_home.setOnClickListener(myOnClickListener);
icon_menu.setOnClickListener(myOnClickListener);
} class MyOnClickListener implements View.OnClickListener { @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.icon_home://home键
//如果最外层菜单和中间菜单都是显示的,就都设置为隐藏
if(isShowLevel2){
//隐藏中间菜单
isShowLevel2 = false;
Tools.hideView(level2); if(isShowLevel3){
//隐藏最外层菜单
isShowLevel3 = false;
Tools.hideView(level3,200);
}
}else{
//显示中间菜单
isShowLevel2 = true;
Tools.showView(level2);
}
//如果都是隐藏的,就仅显示中间菜单 break;
case R.id.icon_menu://菜单键 if(isShowLevel3){
//隐藏
isShowLevel3 = false;
Tools.hideView(level3);
}else{
//显示
isShowLevel3 = true;
Tools.showView(level3);
}
break;
}
}
}
}

在显示和隐藏布局的时候,我抽出了一个工具类用于实现旋转动画,工具类代码如下。

package com.itcast.youkumenu;

import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; /**
* 显示和隐藏指定的控件
*/
class Tools { public static void hideView(View view) {
hideView(view,0);
} public static void showView(View view) {
RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
view.startAnimation(ra);
} public static void hideView(View view, int startOffset) {
RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
ra.setStartOffset(startOffset);//设置动画延迟时间
view.startAnimation(ra);
}
}

运行项目,效果如下。



现在我们要实现一下点击menu键也能隐藏圆环。要想实现这个效果,就得对手机按钮进行控制。

重新修改MainActivity的代码。

package com.itcast.youkumenu;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast; public class MainActivity extends AppCompatActivity { private RelativeLayout level1;
private RelativeLayout level2;
private RelativeLayout level3;
private ImageView icon_menu;
private ImageView icon_home; /**
* 是否显示最外层圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel3 = true; /**
* 是否显示中间圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel2 = true; /**
* 是否显示最里层圆环
* true:显示
* false:隐藏
*/
private boolean isShowLevel1 = true; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); } private void initView() {
level3 = (RelativeLayout) findViewById(R.id.level3);
icon_menu = (ImageView) findViewById(R.id.icon_menu);
level2 = (RelativeLayout) findViewById(R.id.level2);
icon_home = (ImageView) findViewById(R.id.icon_home);
level1 = (RelativeLayout) findViewById(R.id.level1); MyOnClickListener myOnClickListener = new MyOnClickListener();
//设置点击事件
icon_home.setOnClickListener(myOnClickListener);
icon_menu.setOnClickListener(myOnClickListener);
} class MyOnClickListener implements View.OnClickListener { @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.icon_home://home键
//如果最外层菜单和中间菜单都是显示的,就都设置为隐藏
if(isShowLevel2){
//隐藏中间菜单
isShowLevel2 = false;
Tools.hideView(level2); if(isShowLevel3){
//隐藏最外层菜单
isShowLevel3 = false;
Tools.hideView(level3,200);
}
}else{
//显示中间菜单
isShowLevel2 = true;
Tools.showView(level2);
}
//如果都是隐藏的,就仅显示中间菜单 break;
case R.id.icon_menu://菜单键 if(isShowLevel3){
//隐藏
isShowLevel3 = false;
Tools.hideView(level3);
}else{
//显示
isShowLevel3 = true;
Tools.showView(level3);
}
break;
}
}
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU){ //如果三个圆环是显示的,就全部隐藏
if (isShowLevel1){
isShowLevel1 = false;
Tools.hideView(level1);
if(isShowLevel2){
//隐藏中间圆环
isShowLevel2 = false;
Tools.hideView(level2,200); if (isShowLevel3){
//隐藏最外层圆环
isShowLevel3 = false;
Tools.hideView(level3,400);
}
}
}else{
//如果最里层圆环和中间圆环是隐藏的,就显示
//显示最里层圆环
isShowLevel1 = true;
Tools.showView(level1); //显示中间圆环
isShowLevel2 = true;
Tools.showView(level2,200);
} return true;
}
return super.onKeyDown(keyCode, event);
}
}

工具类代码。

package com.itcast.youkumenu;

import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; /**
* 显示和隐藏指定的控件
*/
class Tools { public static void hideView(View view) {
hideView(view,0);
} public static void showView(View view) {
showView(view,0);
} public static void hideView(View view, int startOffset) {
RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
ra.setStartOffset(startOffset);//设置动画延迟时间
view.startAnimation(ra);
} public static void showView(View view, int startOffset) {
RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
ra.setStartOffset(startOffset);
view.startAnimation(ra);
}
}

运行项目,效果如下。



这样就实现了再点击手机的menu键时圆环旋转消失,但是这样就产生了一个bug,不知道观察了上面的动图大家发现bug没有,当我按menu键隐藏圆环时,我再去点击圆环的位置,圆环还是旋转出来了,按道理我们的圆环消失后,就不能被我们点击出来了吧。这里就涉及到了普通动画和属性动画的区别了。当然,解决办法有很多,我这里介绍两种。

第一种,给每个孩子设置不可以点击。

那很多人就有点子了,可以在Tools类的hideView()方法中添加view.setEnabled(false);,然后在showView()方法中添加view.setEnabled(true);,有些人以为这样就能够解决bug了。其实以为这样可以解决问题的人,他就不了解View和ViewGroup的区别,View是不能够对孩子进行操作的,而我们在方法中将传递过来的布局转换为了View,它原先的某些属性就丢失了。其实,对view参数设置了不可点击的话,相对布局确实变得无法被点击了,但是,它的孩子还是可以被点击的。那应该怎么办呢?我们把Tools类中的四个方法的View参数全部改为ViewGroup,然后对ViewGroup的孩子进行禁止点击的操作。具体代码如下。

package com.itcast.youkumenu;

import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; /**
* 显示和隐藏指定的控件
*/
class Tools { public static void hideView(ViewGroup view) {
hideView(view,0);
} public static void showView(ViewGroup view) {
showView(view,0);
} public static void hideView(ViewGroup view, int startOffset) {
RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
ra.setStartOffset(startOffset);//设置动画延迟时间
view.startAnimation(ra); for(int i = 0;i < view.getChildCount();i++){
View childView = view.getChildAt(i);
//设置不可以点击
childView.setEnabled(false);
}
} public static void showView(ViewGroup view, int startOffset) {
RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2, view.getHeight());
ra.setDuration(500);//设置动画播放持续时间
ra.setFillAfter(true);//动画停留在播放完成的状态
ra.setStartOffset(startOffset);
view.startAnimation(ra); for(int i = 0;i < view.getChildCount();i++){
View childView = view.getChildAt(i);
//设置不可以点击
childView.setEnabled(true);
}
}
}

这时你再运行项目,然后点击menu键隐藏圆环后,不管你怎么点击,圆环都不会再出来了。

第二种方法,前面也说到了,我们可以通过属性动画解决该bug。

属性动画和普通动画的区别在于,普通动画只有视觉效果,而控件不会改变它的位置;属性动画不仅有动画效果,而且控件会随着动画而改变位置。可以想象,使用属性动画来旋转的话,当动画执行完毕时,布局旋转180度,此时控件都会旋转到屏幕的下方,这样,用户就点击不到控件从而也就不能触发点击事件了。

修改工具类代码。

package com.itcast.youkumenu;

import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; /**
* 显示和隐藏指定的控件
*/
class Tools { public static void hideView(ViewGroup view) {
hideView(view, 0);
} public static void showView(ViewGroup view) {
showView(view, 0);
} public static void hideView(ViewGroup view, int startOffset) {
// RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2, view.getHeight());
// ra.setDuration(500);//设置动画播放持续时间
// ra.setFillAfter(true);//动画停留在播放完成的状态
// ra.setStartOffset(startOffset);//设置动画延迟时间
// view.startAnimation(ra);
//
// for(int i = 0;i < view.getChildCount();i++){
// View childView = view.getChildAt(i);
// //设置不可以点击
// childView.setEnabled(false);
// } //改为属性动画
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0, 180);
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
view.setPivotX(view.getWidth() / 2);
view.setPivotY(view.getHeight());
} public static void showView(ViewGroup view, int startOffset) {
// RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2, view.getHeight());
// ra.setDuration(500);//设置动画播放持续时间
// ra.setFillAfter(true);//动画停留在播放完成的状态
// ra.setStartOffset(startOffset);
// view.startAnimation(ra);
//
// for (int i = 0; i < view.getChildCount(); i++) {
// View childView = view.getChildAt(i);
// //设置不可以点击
// childView.setEnabled(true);
// } //改为属性动画
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 180, 360);
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
view.setPivotX(view.getWidth() / 2);
view.setPivotY(view.getHeight());
}
}

运行项目,效果和原来相同,但是bug却已经解决了,大家可以自己试一试,原理我也已经说过了。对于动画,Android中分了三个部分,补间动画、帧动画、属性动画,动画的话,我也会在今后的博客中专门讲解一下。那么今天的内容就到这里了。

点击下载源码

Android进阶之绘制-自定义View完全掌握(一)的更多相关文章

  1. Android进阶之绘制-自定义View完全掌握(四)

    前面的案例中我们都是使用系统的一些控件通过组合的方式来生成我们自定义的控件,自定义控件的实现还可以通过自定义类继承View来完成.从该篇博客开始,我们通过自定义类继承View来实现一些我们自定义的控件 ...

  2. Android进阶之绘制-自定义View完全掌握(二)

    这是自定义View系列的第二篇博客,我们继续来学习关于自定义View的知识. 今天我们来实现一下广告条案例. 我们要实现的是这样的一个效果. 要想实现这样的效果,我们可以借助ViewPager控件,然 ...

  3. Android进阶之绘制-自定义View完全掌握(三)

    自定义View系列的第三篇博客,我们来学习如何实现自定义下拉框. 今天的程序,我们来实现这样的一个效果. 布局非常简单,我们直接开始编码. 修改activity_main.xml文件的代码. < ...

  4. Android进阶之绘制-自定义View完全掌握(五)

    在自定义类继承View实现自定义控件的过程中,我们还应该对一些自定义属性有所了解. 我们通过一个案例来学习一下. 新建一个android项目,然后我们创建一个类MyAttributeView继承Vie ...

  5. Android显示框架:自定义View实践之绘制篇

    文章目录 一 View 二 Paint 2.1 颜色处理 2.2 文字处理 2.3 特殊处理 三 Canvas 3.1 界面绘制 3.2 范围裁切 3.3 集合变换 四 Path 4.1 添加图形 4 ...

  6. 【Android - 进阶】之自定义视图浅析

    1       概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDra ...

  7. 【Android 应用开发】自定义View 和 ViewGroup

    一. 自定义View介绍 自定义View时, 继承View基类, 并实现其中的一些方法. (1) ~ (2) 方法与构造相关 (3) ~ (5) 方法与组件大小位置相关 (6) ~ (9) 方法与触摸 ...

  8. Android ——利用OnDraw实现自定义View(转)

    自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.本文将介绍自绘控件的用法.自绘控件的意思是,这个控件上的内容是用onDraw函数绘制出来的.关于onDraw函数的介绍可参看 ...

  9. Android 用属性动画自定义view的渐变背景

    自定义view渐变背景,同时监听手势自动生成小圆球. 宿主Activity如下: package com.edaixi.tempbak; import java.util.ArrayList; imp ...

随机推荐

  1. 个人永久性免费-Excel催化剂功能第29波-追加中国特色的中文相关自定义函数

    中文世界里,有那么几个需求在原生Excel里没提供,例如财务部的数字转大写金额,文字转拼音等,在其他插件里,大部分是以功能区菜单按钮的方式提供.Excel催化剂认为,最佳的使用方式乃是自定义函数的方式 ...

  2. Excel催化剂开源第23波-VSTO开发辅助录入功能关键技术

    Excel催化剂开源第23波-VSTO开发辅助录入功能关键技术 Excel催化剂   2019.01.12 14:10* 字数 2948 阅读 41评论 0喜欢 0 编辑文章 在Excel催化剂的几大 ...

  3. IT界的复仇者联盟解读

    漫威宇宙应用到IT界也是可以解读的,自从编程语言分了派系后,故事就多了,今天我们就用漫威宇宙的故事来解读一下IT界的故事. 漫威宇宙其实也就讲了一件事,整个宇宙就好比一个Java项目,其中有一群叫做美 ...

  4. PHP对接口执行效率慢的优化

    PHP对接口执行效率慢的优化 PHP对接口执行效率慢的优化 造成执行效率低的原因可以由很多方面找原因 从代码层面,代码质量低,执行效率也会有很大影响的. 从硬件方面,服务器配置低,服务器配置是基础,这 ...

  5. handlerMapping的初始化以及查找handler

    前提:HttpServletBean初始化了一些servlet配置,接着FrameWorkServlet创建了WebApplicationContext,最后DispatcherServlet初始化一 ...

  6. (读论文)推荐系统之ctr预估-NFM模型解析

    本系列的第六篇,一起读论文~ 本人才疏学浅,不足之处欢迎大家指出和交流. 今天要分享的是另一个Deep模型NFM(串行结构).NFM也是用FM+DNN来对问题建模的,相比于之前提到的Wide& ...

  7. PAY8 数字货币支付结算系统,全球付!实时结算!秒到账!

    数字货币支付是历史发展的必然 如今已经有越来越多的地方接受加密数字货币作为支付消费了,比如泰国电影院连锁店 Cineplex Group 可用加密货币买爆米花和电影票,西班牙一精品酒店接受数字货币支付 ...

  8. 从三个语言(C++,Java,.Net)的几个性能测试案例来看性能优化

    随着时间的发展,现在的虚拟机技术越来越成熟了,在有些情况下,Java,.Net等虚拟机密集计算的性能已经和C++相仿,在个别情况下,甚至还要更加优秀.本文详细分析几个性能测试案例,探讨现象背后的原因. ...

  9. Docker部署ELK 日志归集

    ELK ELK是Elasticsearch.Logstash.Kibana的缩写,使用ELK的原因是因为公司使用Spring cloud部署了多个微服务,不同的微服务有不同的日志文件,当生产上出现问题 ...

  10. golang-http 请求---设置header与直接发

    背景 现在各种软件到处都是,写代码难免有时候需要http 调用其他的接口. 其实这个东西还挺常用,虽然很简单,但是写的时候 又忘,就像是提笔忘字,索性总结一下吧. 不需要设置header属性的http ...