Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现


我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用ListView太久远了,导致对他已经有浓厚的感情了,我们之前也是写过几篇关于ListView的博文

而今天我们就来实现以下课拖拽的方案,大家可以借鉴以下

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如?

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv_logo"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_centerInParent="true"
        android:layout_marginLeft="10dp"/>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/iv_logo"/>

</RelativeLayout>

这就只有一个头像和一句话了,然后我们把实体类也给写完了

DragBean

package com.liuguilin.draglistviewsample.entity;

/*
 *  项目名:  DragListViewSample
 *  包名:    com.liuguilin.draglistviewsample.entity
 *  文件名:   DragBean
 *  创建者:   LGL
 *  创建时间:  2016/8/29 22:49
 *  描述:    实体类
 */

public class DragBean {

    private int ivId;
    private String text;

    public DragBean() {

    }

    public DragBean(int ivId, String text) {
        this.ivId = ivId;
        this.text = text;
    }

    public int getIvId() {
        return ivId;
    }

    public String getText() {
        return text;
    }

}

ok,其实很简单,id是图片,然后是文本,这样我们就可以来实现一个Adapter了,这里我用的是ArrayAdapter这样能让我们插入和删除很轻松

DragAdapter

package com.liuguilin.draglistviewsample.adapter;

/*
 *  项目名:  DragListViewSample
 *  包名:    com.liuguilin.draglistviewsample.adapter
 *  文件名:   DragAdapter
 *  创建者:   LGL
 *  创建时间:  2016/8/29 22:41
 *  描述:    拖拽列表的数据源
 */

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.liuguilin.draglistviewsample.R;
import com.liuguilin.draglistviewsample.entity.DragBean;

import java.util.List;

public class DragAdapter extends ArrayAdapter<DragBean> {

    /**
     * 构造方法
     *
     * @param context
     * @param mList
     */
    public DragAdapter(Context context, List<DragBean> mList) {
        super(context, 0, mList);
    }

    /**
     * 实现View
     *
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = View.inflate(getContext(), R.layout.list_item, null);
            viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView) view
                    .findViewById(R.id.iv_logo);
            viewHolder.textView = (TextView) view.findViewById(R.id.textView);
            view.setTag(viewHolder);
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }

        viewHolder.imageView.setImageResource(getItem(position).getIvId());
        viewHolder.textView.setText(getItem(position).getText());
        return view;
    }

    /**
     * 缓存
     */
    static class ViewHolder {
        ImageView imageView;
        TextView textView;
    }

}

好的,其实到这里,他就是一个最普通的ListView了,我们给他填充点数据

MainActivity

package com.liuguilin.draglistviewsample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.liuguilin.draglistviewsample.adapter.DragAdapter;
import com.liuguilin.draglistviewsample.entity.DragBean;
import com.liuguilin.draglistviewsample.view.DragListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    //列表
    private DragListView mListView;
    //数据
    private List<DragBean> mList = new ArrayList<>();
    //数据源
    private DragAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    /**
     * 初始化View
     */
    private void initView() {
        mListView = (DragListView) findViewById(R.id.mListView);

        //新增數據
        for (int i = 0; i < 30; i++) {
            DragBean bean = new DragBean(R.mipmap.ic_launcher, "刘某人程序员" + i);
            mList.add(bean);
        }
        //初始化数据源
        adapter = new DragAdapter(this,mList);
        mListView.setAdapter(adapter);
    }
}

现在可以看看实际的效果了

现在我们可以重写我们的ListView了

我们首先拦截他的事件

 /**
     * 获取触点所在条目的位置
     * 获取选中条目的图片
     * 事件的拦截机制
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //识别动作
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //获取触点的坐标
                int x = (int) ev.getX();
                int y = (int) ev.getY();
                //这样就可以计算我按到哪个条目上了
                mStartPosition = mEndPosition = pointToPosition(x, y);
                //判断触点是否在logo的区域
                ViewGroup itemView = (ViewGroup) getChildAt(mStartPosition - getFirstVisiblePosition());
                //记录手指在条目中的相对Y坐标
                dragPoint = y - itemView.getTop();
                //ListView在屏幕中的Y坐标
                dragOffset = (int) (ev.getRawY() - y);
                //拖动的图标
                View dragger = itemView.findViewById(R.id.iv_logo);
                //判断触点是否在logo区域
                if (dragger != null && x < dragger.getRight() + 10) {
                    //定义ListView的滚动条目
                    //上
                    upScroll = getHeight() / 3;
                    //下
                    downScroll = getHeight() * 2 / 3;
                    //获取选中的图片/截图
                    itemView.setDrawingCacheEnabled(true);
                    //获取截图
                    Bitmap bitMap = itemView.getDrawingCache();
                    //图片滚动
                    startDrag(bitMap, y);
                }
                break;
        }
        //还会传递事件到子View
        return false;
    }

获取到他的position之后我们直接截图,并且显示我们的window,这里做的事情就比较多了我们还要判断是否点击的是头像才去显示window

 /**
     * 图片在Y轴,也就是上下可滚动
     *
     * @param bitMap
     * @param y
     */
    private void startDrag(Bitmap bitMap, int y) {
        //窗体仿照
        wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        //设置窗体参数
        lParams = new WindowManager.LayoutParams();
        //设置宽高
        lParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        lParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //属性
        lParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        //设置半透明
        lParams.alpha = 0.8f;
        //设置居中
        lParams.gravity = Gravity.TOP;
        //设置xy
        lParams.x = 0;
        lParams.y = y-dragPoint + dragOffset;
        //属性
        lParams.format = PixelFormat.TRANSLUCENT;
        //设置动画
        lParams.windowAnimations = 0;
        //图片
        dragImageView = new ImageView(getContext());
        //设置截图
        dragImageView.setImageBitmap(bitMap);
        //添加显示窗体
        wm.addView(dragImageView, lParams);
    }

好的,我们初始化一下window,光显示还不行呢,我们还要可以滑动,怎么监听?onTouchEvent的ACTION_MOVE事件是可以做到的


    /**
     * 触摸事件
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //错误的位置
        if (dragImageView != null && mEndPosition != INVALID_POSITION) {
            //在滑动事件中控制上下滑动
            switch (ev.getAction()) {
                case MotionEvent.ACTION_MOVE:
                    //直接获取到Y坐标进行移动
                    int moveY = (int) ev.getY();
                    doDrag(moveY);
                    break;
                //停止拖动成像
                case MotionEvent.ACTION_UP:
                    int upY = (int) ev.getY();
                    stopDrag();
                    onDrag(upY);
                    break;
            }
        }
        //拦截到事件
        return true;
    }

我们在移动的时候不断的去更新他的位置

    /**
     * 控制窗体移动
     *
     * @param moveY
     */
    private void doDrag(int moveY) {
        if (dragImageView != null) {
            lParams.y = moveY - dragPoint + dragOffset;
            wm.updateViewLayout(dragImageView, lParams);
        }
        //判断移动到分割线 返回-1
        int tempLine = pointToPosition(0, moveY);
        //我们处理他
        if (tempLine != INVALID_POSITION) {
            //只要你不移动到分割线 我才处理
            mEndPosition = tempLine;
        }

        //拖拽时滚动、滚动速度
        int scrollSpeed = 0;
        //上滚
        if (moveY < upScroll) {
            scrollSpeed = 10;
            //下滚
        } else if (moveY > downScroll) {
            scrollSpeed = -10;
        }
        //开始滚动
        if (scrollSpeed != 0) {
            //计算条目的Y坐标
            int dragItemY = getChildAt(mEndPosition - getFirstVisiblePosition()).getTop();
            //当前速度
            int dy = dragItemY + scrollSpeed;
            //设置
            setSelectionFromTop(mEndPosition, dy);
        }
    }

当你移动完成之后,我就可以停止你的window体了

     /**
     * 停止的位置
     */
    private void stopDrag() {
        //直接移除窗体
        if (dragImageView != null) {
            wm.removeView(dragImageView);
            dragImageView = null;
        }

    }

这样,我就直接拼接你的position达到一个拖拽的效果


    /**
     * 最终开始成像
     *
     * @param upY
     */
    private void onDrag(int upY) {
        //分割线的处理
        //判断移动到分割线 返回-1
        int tempLine = pointToPosition(0, upY);
        //我们处理他
        if (tempLine != INVALID_POSITION) {
            //只要你不移动到分割线 我才处理
            mEndPosition = tempLine;
        }

        /**
         * 你在最上方就直接落在第一个最下方就直接最下面一个
         */

        //上边界处理
        if (upY < getChildAt(1).getTop()) {
            mEndPosition = 1;
            //下边界处理
        } else if (upY > getChildAt(getChildCount() - 1).getTop()) {
            mEndPosition = getAdapter().getCount() - 1;
        }

        //开始更新item顺序
        if (mEndPosition > 0 && mEndPosition < getAdapter().getCount()) {
            DragAdapter adapter = (DragAdapter) getAdapter();
            //删除原来的条目
            adapter.remove(adapter.getItem(mStartPosition));
            //更新
            adapter.insert(adapter.getItem(mStartPosition), mEndPosition);
        }
    }

全部代码贴上

DragListView

package com.liuguilin.draglistviewsample.view;

/*
 *  项目名:  DragListViewSample
 *  包名:    com.liuguilin.draglistviewsample.view
 *  文件名:   DragListView
 *  创建者:   LGL
 *  创建时间:  2016/8/29 20:50
 *  描述:    自定义高仿QQ列表可拖拽的ListView
 */

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListView;

import com.liuguilin.draglistviewsample.R;
import com.liuguilin.draglistviewsample.adapter.DragAdapter;

public class DragListView extends ListView {

    //按下选中的position
    private int mStartPosition;
    //需要达到的position
    private int mEndPosition;
    //手指在条目中的相对Y坐标
    private int dragPoint;
    //ListView在屏幕中的Y坐标
    private int dragOffset;
    //上
    private int upScroll;
    //下
    private int downScroll;
    //窗体
    private WindowManager wm;
    //显示的截图
    private ImageView dragImageView;
    //窗体参数
    private WindowManager.LayoutParams lParams;

    //构造方法
    public DragListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 获取触点所在条目的位置
     * 获取选中条目的图片
     * 事件的拦截机制
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //识别动作
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //获取触点的坐标
                int x = (int) ev.getX();
                int y = (int) ev.getY();
                //这样就可以计算我按到哪个条目上了
                mStartPosition = mEndPosition = pointToPosition(x, y);
                //判断触点是否在logo的区域
                ViewGroup itemView = (ViewGroup) getChildAt(mStartPosition - getFirstVisiblePosition());
                //记录手指在条目中的相对Y坐标
                dragPoint = y - itemView.getTop();
                //ListView在屏幕中的Y坐标
                dragOffset = (int) (ev.getRawY() - y);
                //拖动的图标
                View dragger = itemView.findViewById(R.id.iv_logo);
                //判断触点是否在logo区域
                if (dragger != null && x < dragger.getRight() + 10) {
                    //定义ListView的滚动条目
                    //上
                    upScroll = getHeight() / 3;
                    //下
                    downScroll = getHeight() * 2 / 3;
                    //获取选中的图片/截图
                    itemView.setDrawingCacheEnabled(true);
                    //获取截图
                    Bitmap bitMap = itemView.getDrawingCache();
                    //图片滚动
                    startDrag(bitMap, y);
                }
                break;
        }
        //还会传递事件到子View
        return false;
    }

    /**
     * 图片在Y轴,也就是上下可滚动
     *
     * @param bitMap
     * @param y
     */
    private void startDrag(Bitmap bitMap, int y) {
        //窗体仿照
        wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        //设置窗体参数
        lParams = new WindowManager.LayoutParams();
        //设置宽高
        lParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        lParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //属性
        lParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        //设置半透明
        lParams.alpha = 0.8f;
        //设置居中
        lParams.gravity = Gravity.TOP;
        //设置xy
        lParams.x = 0;
        lParams.y = y-dragPoint + dragOffset;
        //属性
        lParams.format = PixelFormat.TRANSLUCENT;
        //设置动画
        lParams.windowAnimations = 0;
        //图片
        dragImageView = new ImageView(getContext());
        //设置截图
        dragImageView.setImageBitmap(bitMap);
        //添加显示窗体
        wm.addView(dragImageView, lParams);
    }

    /**
     * 触摸事件
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //错误的位置
        if (dragImageView != null && mEndPosition != INVALID_POSITION) {
            //在滑动事件中控制上下滑动
            switch (ev.getAction()) {
                case MotionEvent.ACTION_MOVE:
                    //直接获取到Y坐标进行移动
                    int moveY = (int) ev.getY();
                    doDrag(moveY);
                    break;
                //停止拖动成像
                case MotionEvent.ACTION_UP:
                    int upY = (int) ev.getY();
                    stopDrag();
                    onDrag(upY);
                    break;
            }
        }
        //拦截到事件
        return true;
    }

    /**
     * 最终开始成像
     *
     * @param upY
     */
    private void onDrag(int upY) {
        //分割线的处理
        //判断移动到分割线 返回-1
        int tempLine = pointToPosition(0, upY);
        //我们处理他
        if (tempLine != INVALID_POSITION) {
            //只要你不移动到分割线 我才处理
            mEndPosition = tempLine;
        }

        /**
         * 你在最上方就直接落在第一个最下方就直接最下面一个
         */

        //上边界处理
        if (upY < getChildAt(1).getTop()) {
            mEndPosition = 1;
            //下边界处理
        } else if (upY > getChildAt(getChildCount() - 1).getTop()) {
            mEndPosition = getAdapter().getCount() - 1;
        }

        //开始更新item顺序
        if (mEndPosition > 0 && mEndPosition < getAdapter().getCount()) {
            DragAdapter adapter = (DragAdapter) getAdapter();
            //删除原来的条目
            adapter.remove(adapter.getItem(mStartPosition));
            //更新
            adapter.insert(adapter.getItem(mStartPosition), mEndPosition);
        }
    }

    /**
     * 停止的位置
     */
    private void stopDrag() {
        //直接移除窗体
        if (dragImageView != null) {
            wm.removeView(dragImageView);
            dragImageView = null;
        }

    }

    /**
     * 控制窗体移动
     *
     * @param moveY
     */
    private void doDrag(int moveY) {
        if (dragImageView != null) {
            lParams.y = moveY - dragPoint + dragOffset;
            wm.updateViewLayout(dragImageView, lParams);
        }
        //判断移动到分割线 返回-1
        int tempLine = pointToPosition(0, moveY);
        //我们处理他
        if (tempLine != INVALID_POSITION) {
            //只要你不移动到分割线 我才处理
            mEndPosition = tempLine;
        }

        //拖拽时滚动、滚动速度
        int scrollSpeed = 0;
        //上滚
        if (moveY < upScroll) {
            scrollSpeed = 10;
            //下滚
        } else if (moveY > downScroll) {
            scrollSpeed = -10;
        }
        //开始滚动
        if (scrollSpeed != 0) {
            //计算条目的Y坐标
            int dragItemY = getChildAt(mEndPosition - getFirstVisiblePosition()).getTop();
            //当前速度
            int dy = dragItemY + scrollSpeed;
            //设置
            setSelectionFromTop(mEndPosition, dy);
        }
    }
}

然后我们引用

layout_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <com.liuguilin.draglistviewsample.view.DragListView
        android:id="@+id/mListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

对了,别忘记了添加窗体的权限哦

 <!--窗口权限-->
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

做完这一系列事情之后,就觉得这个设想其实是对的,然后我们可以尝试性的运行一下

运行时成功的,说明我们的设想是没有问题的,但是随着而来的,也是诸多的bug,所以呢,这也只是思想的参考,不过这些bug我有时间野就修复一下,应该是可以的,好的,本篇博文就先到这里!

有兴趣的加群:555974449

DragListViewSample:http://download.csdn.net/detail/qq_26787115/9616355

Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现的更多相关文章

  1. Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例

    Android高级控件(五)--如何打造一个企业级应用对话列表,以QQ,微信为例 看标题这么高大上,实际上,还是运用我么拿到listview去扩展,我们讲什么呢,就是研究一下QQ,微信的这种对话列表, ...

  2. Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...

  3. Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,添加和删除等功能 这个控件还是挺复杂的.也是项目中应该算是比較经常使用的了,所以写了一个小Demo来讲讲,主要是自己定义a ...

  4. Android高级控件--AdapterView与Adapter

    在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...

  5. Android 高级控件(七)——RecyclerView的方方面面

    Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...

  6. Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现

    Android高级控件(二)--SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现 写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还 ...

  7. Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷

    Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...

  8. Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系

    Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 现在的二维码可谓是烂大街了,到处都是二维码,什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...

  9. Android高级控件(三)——&#160;使用Google ZXing实现二维码的扫描和生成相关功能体系

    Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 如今的二维码可谓是烂大街了.到处都是二维码.什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...

随机推荐

  1. 计蒜客NOIP2017提高组模拟赛(五)day1-展览

    传送门 发现这题选或不选对状态的优劣程度不会产生影响,如果已经确定了两个数a和b,那么最优的首项和公比也都是唯一确定的, 与对于后面的数x,加进去也好不加进去也好,首项和公比依旧是原来的 于是我们用尺 ...

  2. bzoj3675[Apio2014]序列分割 斜率优化dp

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3508  Solved: 1402[Submit][Stat ...

  3. Java文件操作(新建,遍历,删除)

    //创建文件 private static void createFile(File file){ try { if(!file.exists()){ if(file.getParentFile() ...

  4. 【iOS】苹果开发者账号申请

    [1]首先登陆苹果开发者中心:https://developer.apple.com/programs/ 如图有一个按钮enroll,意思是苹果开发者报名(说白了就是要交钱,好让你具备APP测试和上线 ...

  5. 镜像文件、光盘、iso文件、启动盘

    刚入大学,有一门计算机硬件维修课程,韩国彬老师(学生们公认的好老师).当时韩老师教给了我们好多实用的好东西,例如装系统,做镜像文件,装虚拟机,ghost版本系统,计算机组装等等.由于高中刚刚过度到大学 ...

  6. win10下python环境变量设置

    我用的是python_2.7.3.msi,从官网下载之后,一路按照默认进行安装. 安装之后配置环境变量的步骤如下: 1,点“我的电脑”,右键选“属性” 2,选择“高级系统设置”--->选“环境变 ...

  7. Triangle(动态规划)

    题目描述 Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjac ...

  8. Tensorflow从入门到精通之——Tensorflow基本操作

    前边的章节介绍了什么是Tensorflow,本节将带大家真正走进Tensorflow的世界,学习Tensorflow一些基本的操作及使用方法.同时也欢迎大家关注我们的网站和系列教程:http://ww ...

  9. js中对象的自定义排序

    //并返回一个可以用来对包含该成员的对象数组进行排序的比较函数 var compareAsc = function (prop) { return function (obj1, obj2) { va ...

  10. 数据结构之Treap

    1. 概述 同splay tree一样,treap也是一个平衡二叉树,不过Treap会记录一个额外的数据,即优先级.Treap在以关键码构成二叉搜索树的同时,还按优先级来满足堆的性质.因而,Treap ...