Giter Site home page Giter Site logo

laobie / ninegridimageview Goto Github PK

View Code? Open in Web Editor NEW
1.4K 33.0 235.0 202 KB

A custom widget for Android, which used for showing grid pictures.

Home Page: http://t.cn/RGH3uNF

License: Apache License 2.0

Java 100.00%
ninegridview showing-grid-pictures custom-widget android

ninegridimageview's Introduction

NineGridImageView

996.icu

中文版说明点我

This is a custom widget for Android, which uesd for showing grid pictures, such as you seeing in weibo or wechat.

Update Log

  • 1.1.1

    • add longClickListener method
  • 1.1.0

    • modify NineGridImageViewAdapter 's onItemImageClick() method, providing clicked ImageView
    • add setItemImageClickListener() method
  • 1.0.3

    fix return data not original bug

  • 1.0.2

    • remove support library
  • 1.0.1

    • bug fix: if no image data or images size is zero, this view will not show;
    • add set max size of images method;
  • 1.0.0

    first publish

Sample

Download NineGridImageView-Demo

Features

  • set gap between images

    app:imgGap="4dp" or nineGridImageView.setGap(int gap);

    • set max size of images()

    app:maxSize="9" or nineGridImageView.setMaxSize(int maxSize);

    if maxSize Less than or equal to 0, there may not limit for images size.

  • set style

    app:showStyle="fill" or nineGridImageView.setShowStyle(int style);

    default style is STYLE_GRID:

    another style is STYLE_FILL:

  • when only one image, you can set it's size by:

    app:singleImgSize="120dp" or nineGridImageView.setSingleImgSize(int singleImgSize)

Usage

1. Add the dependencies to your build.gradle file, NineGridImageView is avaiable in JCenter:
compile 'com.jaeger.ninegridimageview:library:1.1.1'
2. Add the NineGridImageView to your layout XML:
<com.jaeger.ninegridimageview.NineGridImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"
    android:layout_width="match_parent"
    app:imgGap="4dp"
    app:showStyle="fill"
    app:singleImgSize="120dp"/>
3. set a NineGridImageViewAdapter for NineGridImageView
nineGridImageView.setAdapter(nineGridViewAdapter);

Here is NineGridImageViewAdapter.class source code: ​

public abstract class NineGridImageViewAdapter<T> {

    protected abstract void onDisplayImage(Context context, ImageView imageView, T t);

    protected void onItemImageClick(Context context, ImageView imageView, int index, List<T> list) {
    
    }

    protected ImageView generateImageView(Context context) {
        GridImageView imageView = new GridImageView(context);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        return imageView;
    }
}			
  • T is your image data model, you can simple use String or your own model
  • you must override onDisplayImage(Context context, ImageView imageView, T t) method to set load image way, you can use Picasso, Glide or ImageLoader etc, and you can also set place holder for ImageView.
  • if you need handle image click event, you can override onItemImageClick(Context context, int index, List<T> list) method, it is easy to handle image click event.
  • if you want to customize ImageView, you can override generateImageView(Context context) method, to generate your custom ImageView.

Here is sample code: ​

private NineGridImageViewAdapter<Photo> mAdapter = new NineGridImageViewAdapter<Photo>() {
	@Override
	protected void onDisplayImage(Context context, ImageView imageView, Photo photo) {
		Picasso.with(context)
		    .load(photo.getSmallUrl)
		    .placeholder(R.drawable.ic_default_image)
		    .into(imageView);
    }

    @Override
    protected ImageView generateImageView(Context context) {
        return super.generateImageView(context);
    }

    @Override
    protected void onItemImageClick(Context context, ImageView imageView, int index, List<Photo> photoList) {
       showBigPicture(context, photoList.get(index).getBigUrl());
    }
};
        
...
	mNineGridImageView.setAdapter(mAdapter);
...
4. set pictures data for NineGridImageView
nineGridImageView.setImagesData(List<T> imageDataList);
5. set ItemImageClickListener for NineGridImageView
mNineImageView.setItemImageClickListener(new ItemImageClickListener<String>() {
    @Override
    public void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {

    }
});

Credits

License

Copyright 2016 Jaeger Chen

Licensed under the Apache License, Version 2.0 (the "License");	you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

​ ​ ​

ninegridimageview's People

Contributors

gaoneng102 avatar yueban avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ninegridimageview's Issues

滑动时,会出现九宫格控件中的部分图片被放大的效果

猴哥,现在遇到这个情况,我现在测试数据的时候让总的数据集大于九张,那么就会有几个item都是显示九张图片,但是会出现下面的情况?这种情况的复现是:缓慢滑动到最后底部,就会出现这个问题(有时候快速滑动也会出现这个问题),来回滑动到上一个正常的九张图片再滑回来就正常了
ques123
gif太大上传不了。。。
eeff

在特殊情况图片循环被加载。

使用的时候,在三星note4手机,展示6张图片。其中有2张图片会重复加载,图片加载用imageloader。现象是,图片被加载出来就重新再次加载。发生的概率比较小。怀疑是图片展示的回调接口重复调用。

请教个问题

你好,我现在的需求需要在图片上显示视频的类型
image

我在这个地方直接inflate的一个view, 是个 FrameLayout,里面有2个imageview,其它地方也都改了,现在里面的2个imageview不能正常显示,请问下是什么原因,谢谢

针对同一个NineGridImageView对它多次赋值报错了

打了几行日志:

public void setImagesData(List lists) {
        try {
            if (lists == null || lists.isEmpty()) {
                LogUtil.d(TAG, "setImagesData debug, New List = NULL");
                this.setVisibility(GONE);
                return;
            } else {
                LogUtil.d(TAG, "setImagesData debug, New List != NULL, Size = " + lists.size());
                this.setVisibility(VISIBLE);
            }
            LogUtil.d(TAG, "setImagesData debug, Max Size = " + mMaxSize);
            if (mMaxSize > 0 && lists.size() > mMaxSize) {
                lists = lists.subList(0, mMaxSize);
            }
            LogUtil.d(TAG, "setImagesData debug, Show Style = " + mShowStyle);
            int[] gridParam = calculateGridParam(lists.size(), mShowStyle);
            mRowCount = gridParam[0];
            mColumnCount = gridParam[1];
            LogUtil.d(TAG, "setImagesData debug, Row Count = " + mRowCount);
            LogUtil.d(TAG, "setImagesData debug, Column Count = " + mColumnCount);
            if (mImgDataList == null) {
                LogUtil.d(TAG, "setImagesData debug, Old List = NULL");
                int i = 0;
                while (i < lists.size()) {
                    GFImageView iv = getImageView(i);
                    if (iv == null) {
                        return;
                    }
                    addView(iv, generateDefaultLayoutParams());
                    i++;
                }
            } else {
                LogUtil.d(TAG, "setImagesData debug, Old List != NULL");
                int oldViewCount = mImgDataList.size();
                int newViewCount = lists.size();
                if (oldViewCount > newViewCount) {
                    removeViews(newViewCount, oldViewCount - newViewCount);
                } else if (oldViewCount < newViewCount) {
                    for (int i = oldViewCount; i < newViewCount; i++) {
                        GFImageView iv = getImageView(i);
                        if (iv == null) {
                            return;
                        }
                        addView(iv, generateDefaultLayoutParams());
                    }
                }
            }
            mImgDataList = lists;
            requestLayout();
        } catch (Exception e) {
            LogUtil.e(TAG, "setImagesData error", e);
        }
    }

日志输出如下:

04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, New List != NULL, Size = 6
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Max Size = 9
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Show Style = 1
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Row Count = 2
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Column Count = 3
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Old List != NULL
04-18 20:56:51.838 19831-19831/NineGridImageView: setImagesData error
java.lang.IllegalStateException: **The specified child already has a parent. You must call removeView() on the child's parent first.**
at android.view.ViewGroup.addViewInner(ViewGroup.java:4315)
at android.view.ViewGroup.addView(ViewGroup.java:4151)
at android.view.ViewGroup.addView(ViewGroup.java:4123)
at com.way.heard.ui.views.NineGridImageView.setImagesData(NineGridImageView.java:155)
at com.way.heard.ui.activities.WritingActivity$7.onHanlderSuccess(WritingActivity.java:286)
at cn.finalteam.galleryfinal.PhotoBaseActivity.resultData(PhotoBaseActivity.java:186)
at cn.finalteam.galleryfinal.PhotoSelectActivity.onClick(PhotoSelectActivity.java:390)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21265)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

等我解决了过来Comment一下。


来了,mImgDataList的值会莫名其妙的丢失,导致
mImgDataList.size() = 0;
好在博主方法里也没用到mImgDataList里的数据,只用到了size(),用一个静态变量保存一下**size()**的值即可。

我用baserecyclerviewadapterhelper适配时,引用此控件,在6.0系统上 报ninegridview.GridImageView{c03dd20 V.ED..C.. ......ID 0,312-300,612} during layout: running second layout pass

public class HealthAdapter extends BaseQuickAdapter<HealthInfo, BaseViewHolder> {

public HealthAdapter(@LayoutRes int layoutResId, @Nullable ArrayList<HealthInfo> data) {
    super(layoutResId, data);
}
NineGridImageViewAdapter<String> mAdapter = new NineGridImageViewAdapter<String>() {
    @Override
    protected void onDisplayImage(Context context, ImageView imageView, String s) {
        Glide.with(mContext)
                .load(s)
                .placeholder(R.mipmap.load_logo)
                .error(R.mipmap.load_logo)
                .dontAnimate()
                .into(imageView);
    }

    @Override
    protected ImageView generateImageView(Context context) {
        return super.generateImageView(context);
    }

    @Override
    protected void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {

    }
};
@Override
protected void convert(BaseViewHolder helper, HealthInfo item) {


    List<String>  url=new ArrayList<>();
    url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
    url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
    url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
    url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
    TextView  tvTime=helper.getView(R.id.tv_time);
    TextView  tvKind=helper.getView(R.id.tv_kind);
    TextView  tvHospital=helper.getView(R.id.tv_hospital);
    NineGridImageView<String> mNglContent =helper.getView(R.id.ngl_images);

    mNglContent.setAdapter(mAdapter);
    mNglContent.setImagesData(url);
    String date=item.getPre_date().substring(0,10);
    tvTime.setText(date);
    tvKind.setText(item.getMedical_type().equals("0")?"11111":"22222");
    tvHospital.setText("机构:"+item.getOrg_name());


}

singleSize的大小最好有个判断

singleImgSize的大小最好有个判断
当xml中定义的大小超过屏幕尺寸的时候,用屏幕尺寸大小
不然的话xml中定义非常大的时候,显示是不合理的

Glide加载不出来图片???

一直显示占位图,退出再进去才正常显示。弱弱的问下,这个项目作者还更新么。看到好多问题都很久了。。。 (ಥ﹏ಥ)

关闭日志

你的日志怎么关闭了,一直在打印

自定义图片宽高比例实现

首先还是感谢作者提供的开源项目!因为我的图片需要实现的图片不是正方形,而作者的图片都是正方形的。所以,修改了一下,支持可以使用宽高比例图片。大家如果有同样的需求,可以按照这样的方式处理。。也期待作者下个版本上能支持吧!

直接看代码修改吧
` private int[] mGridSize = new int[2]; // 宫格大小,即图片大小,表示宽高值
private float mRatio = 1.0f; //图片宽高比例,默认1:1.为正方形

@OverRide
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
......
if (mImgDataList.size() == 1 && mSingleImgSize != -1) {
mGridSize[0] = mSingleImgSize > totalWidth ? totalWidth : mSingleImgSize;
mGridSize[1] = calculateRatio(mGridSize[0]);
} else {
mImageViewList.get(0).setScaleType(ImageView.ScaleType.CENTER_CROP);
mGridSize[0] = (totalWidth - mGap * (mColumnCount - 1)) / mColumnCount;
mGridSize[1] = calculateRatio(mGridSize[0]);
}
.......
}

/**
根据比例,通过宽的值,计算高
**/
private int calculateRatio(int width) {
return (int) (width * mRatio);
}

/***
设置宽高比例,如宽高3/4。则传入0.75f即可
*/
public void setImageSizeRatio(float ratio) {
this.mRatio = ratio;
}

//然后修改每一个用到宽高的地方代码,如下:
private void layoutForNoSpanChildrenView(int childrenCount) {
if (childrenCount <= 0) return;
int row, column, left, top, right, bottom;
for (int i = 0; i < childrenCount; i++) {
ImageView childrenView = (ImageView) getChildAt(i);
row = i / mColumnCount;
column = i % mColumnCount;
left = (mGridSize[0] + mGap) * column + getPaddingLeft();//用到宽的地方值
top = (mGridSize[1] + mGap) * row + getPaddingTop();//用到高的地方值
right = left + mGridSize[0];//用到宽的地方值
bottom = top + mGridSize[1];//用到高的地方值
childrenView.layout(left, top, right, bottom);
if (mAdapter != null) {
mAdapter.onDisplayImage(getContext(), childrenView, mImgDataList.get(i));
}
}
}
`

说明:源码中是以前是用mGridSize表示图片宽和高的,现在宽高不一样,用一个数组表示。即可。。

目前已经在源码上修改实现了功能。期待作者下版本能加上此功能。。

开源是伟大的。。希望大家都能贡献一点力量。。。

adjustresize模式下RecyclerView中键盘弹出收回造成布局没有被重绘

这种情况只在外边包裹一层或多层view group时发生,on measure没有调用,但是父布局的是调用了的,只能forcelayout暂时解决。复现场景是,在demo中添加一个edittext位于recyclerview下边,activity修改为adjustresize,键盘弹起,窗口resize,奇数次,这时候该控件不会重新布局

onItemImageClick返回的list

protected void onItemImageClick(Context context, int index, List<String> list)
这里的list,目前是返回了显示在屏幕上的list,不应该是原始list吗
比如我的lis是12个元素,但是我默认只显示9个,点击之后才跳到新页面来显示所有的元素

或者说回调多一个参数呢,比如变成
protected void onItemImageClick(Context context, int index, List<String> list,List<String> initList)

能否不控制图片9张的上限

能否不限制图片上限,我在NineGridImageView中把下面的注释了就好了,因为如果做一个时间轴的demo,不能保证每一个item最多9张图,或者超过了9张提供接口控制。
if (lists.size() > 9) {
lists = lists.subList(0, 9);
}
另外图片的点击背景效果最好可以提供接口修改。

使用Glide4.0有些图片无法显示

Glide最新的4.0 apply(baseOptions)后很多图片不能加载出来,不设置则没有问题,具体代码如下。
public class PostViewHolder extends RecyclerView.ViewHolder {
private NineGridImageView mNglContent;
private TextView mTvContent;
private RequestOptions baseOptions;

    private NineGridImageViewAdapter<String> mAdapter = new NineGridImageViewAdapter<String>() {

        @Override
        protected void onDisplayImage(Context context, ImageView imageView, String s) {

            Glide.with(context).load(s).apply(baseOptions).into(imageView);

// Picasso.with(context).load(s).placeholder(R.drawable.ic_default_image).into(imageView);
}

        @Override
        protected ImageView generateImageView(Context context) {
            return super.generateImageView(context);
        }

        @Override
        protected void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {
            Toast.makeText(context, "image position is " + index, Toast.LENGTH_SHORT).show();
        }
    };

    public PostViewHolder(View itemView) {
        super(itemView);
        baseOptions = new RequestOptions()
                .dontAnimate()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .centerCrop()
                .circleCrop()
                .placeholder(R.drawable.ic_default_image)
                .error(R.drawable.ic_default_image);
        mTvContent = (TextView) itemView.findViewById(R.id.tv_content);
        mNglContent = (NineGridImageView<String>) itemView.findViewById(R.id.ngl_images);
        mNglContent.setAdapter(mAdapter);
        mNglContent.setItemImageClickListener(new ItemImageClickListener<String>() {
            @Override
            public void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {
                Log.d("onItemImageClick", list.get(index));
            }
        });
    }

    public void bind(Post post) {
        mNglContent.setImagesData(post.getImgUrlList(), post.getmSpanType());
        mTvContent.setText(post.getContent());

        Log.d("jaeger", "九宫格高度: " + mNglContent.getMeasuredHeight());
        Log.d("jaeger", "item 高度: " + itemView.getMeasuredHeight());
    }
}

item监听为什么放在adapter中啊?

一般控件的监听不应该是类似 listview.setOnItemClickListener()么,是通过控件来设置item监听的。这个库是放在adapter中的,为什么这么做呢?

如果图片地址错误,设置一个错误显示的位图,会导致```onDisplayImage```不停重复调用

如果图片地址错误,设置一个错误显示的位图,会导致onDisplayImage不停重复调用。
把Demo中的加载图片的这段

Picasso.with(context).load(s).placeholder(R.drawable.ic_default_image).into(imageView);

改成

Picasso.with(context).load(s).error(R.drawable.ic_default_image).into(imageView);

再把图片地址换成一个错误的,就能复现了。

Picasso 和 Glide 都有这种问题。

水平有限不知道什么原因,还希望作者看看

断点调试,发现无法实现复用

作者你好,在调试您的这个九宫格控件的时候遇到些问题。假设列表中第一个item中有一张图片,第二个item有三张图片。发现mImgDataList第一次为null,这个时候就可以添加imageview布局将图片显示上去,当显示第二个item时,按理说这个时候mImgDataList的size为1了,就应该走else语句了,去再new两个imageview即可。但是断点调试的结果是,显示第二个item的时候,走这个if-else语句时,mImgDataList仍为null。这样的话就相当于new三个imageview,无法重用。如下图
quest
希望作者能抽时间解答下,谢谢~

NineGridImageView一个建议

NineGridImageView类中setImagesData(List lists)方法中mImgDataList = lists;这样导致mImgDataList 与传入的参数的内存地址一致,会使oldShowCount与newShowCount的判断永远相等,使第二次调用setImagesData(List lists)报错崩溃。
应该将mImgDataList = lists;修改为mImgDataList = new ArrayList<>(lists);,这样保证了原本作者的意图。

关于 使用 Glide 用了 placeholder 死循环解决方案

@OverRide
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("loadSquareSmallWallpaperData", "changed=" + changed + ",isonDetachedFromWindow=" + isDetachedFromWindow);
if (changed || isReDraw) {
isReDraw = false;
layoutChildrenView();
}
}

boolean isDetachedFromWindow = false;
boolean isReDraw = false;

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    isDetachedFromWindow = true;
    Log.i("loadSquareSmallWallpaperData", "onDetachedFromWindow");
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (isDetachedFromWindow) {
        isDetachedFromWindow = false;
        isReDraw = true;

    }
    Log.i("loadSquareSmallWallpaperData", "onAttachedToWindow");
}

转场动画的实现

需要做点击图片查看详情的时候,有个放大缩小的功能,那就要获取到当前的ImageView,onItemImageClick能返回这个View吗

咨询个问题

在使用的过程中,看到日志中不停的打印出requestLayout,我想问一下这样产生的原因是什么,对性能会不会有很大的影响?

使用Glide不能下载图片,Picasso可以

// Picasso.with(context)
// .load(o.getUrl())
// .placeholder(R.mipmap.default_no_order)
// .into(imageView);

            GlideApp.with(context)
                    .load(o.getUrl())
                    .transition(new DrawableTransitionOptions().dontTransition())
                    .apply(getRequestOptions())
                    .into(imageView);

当图片没有的时候出现错乱

考虑当图片没有的时候,recyclerView会出现错乱,这个算是一个改进建议吧~作为ViewGroup,在bind的时候因为是动态添加子view的,首先调用removeAllViews或者判断一下list的size是否妥当写些?

在第二次调用setImagesData后mImgDataList的大小变得跟传入的数据大小一致

int oldShowCount = getNeedShowCount(mImgDataList.size());
if (oldShowCount > newShowCount) {
removeViews(newShowCount, oldShowCount - newShowCount);
} else if (oldShowCount < newShowCount) {
for (int i = oldShowCount; i < newShowCount; i++) {
ImageView iv = getImageView(i);
if (iv == null) {
return;
}
addView(iv, generateDefaultLayoutParams());
}
}
这段代码不会执行,造成崩溃

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.