【Android】快速开发偷懒必备(二) 支持DataBinding啦~爽炸,一行实现花式列表

转载请标明出处:

http://blog.csdn.net/zxt0601/article/details/53618694

本文出自:【张旭童的博客】(http://blog.csdn.net/zxt0601)

代码传送门:喜欢的话,随手点个star。多谢

https://github.com/mcxtzhang/all-base-adapter

概述

在前文快速开发偷懒必备(一)中,我们利用Adapter模式封装了一个库,能快速为任意ViewGroup添加子View。

有如下特点:

* 快速简单使用

* 支持任意ViewGroup

* 无耦合

* 无侵入性

* Item支持多种类型

在库中V1.1.0版本,我也顺手加入了RecyclerView、ListView、GridView的通用Adapter功能,库地址在这里。

现在V1.2.0版本发布,我又加入了我最近超爱的一个技术,DataBinding

封装了一套一行代码实现花式列表的Adapter

即利用DataBinding实现RecyclerView中快速使用的Adapter。

以后不管写多种type还是单type的列表,利用DataBinding本库,都只需要一行代码

这里也算是安利DataBinding吧,真的超好用。还没使用的朋友们,在看到本文可以如此简单写花式列表后,建议去学习一下。

先看用法吧,简单粗暴到没朋友。

用法

使用必读:

BaseBindingAdapter利用DataBinding提供的动态绑定技术,使用BR.data封装数据、BR.itemP封装点击事件。所以对layout有以下要求:

  • layout中 数据name起名data
  • layout中 点击事件Presenter起名 itemP

如:

<layout 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">
    <data>
        <variable
            name="itemP"
            type="mcxtzhang.commonviewgroupadapter.databinding.rv.single.DBSingleActivity.SingleItemPresenter"/>
        <variable
            name="data"
            type="mcxtzhang.commonviewgroupadapter.databinding.rv.single.DBSingleBean"/>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="1dp"
        android:background="@color/colorAccent"
        android:onClick="@{v->itemP.onItemClick(data)}"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/ivAvatar"
            android:layout_width="200dp"
            android:layout_height="200dp"
            app:netUrl="@{data.avatar}"
            tools:src="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{data.name}"
            tools:text="测试多种"/>
    </LinearLayout>
</layout>

1 单Item列表

效果如图:

顺带演示了BaseBindingAdapter封装的一些增删功能。

用法:

和其他BaseAdapter用法一致:

* 构造函数只需要传入context,datas,layout

    mAdapter = new BaseBindingAdapter(this, mDatas, R.layout.item_db_single);

好了,列表已经出来了。我不骗你,就这一句话。

如果需要设置点击事件(点击事件设置所有类型都一样,下不赘述):

    //★ 设置Item点击事件
    mAdapter.setItemPresenter(new SingleItemPresenter());
    /**
     * ★ Item点击事件P
     */
    public class SingleItemPresenter {
        public void onItemClick(DBSingleBean data) {
            data.setName("修改之后立刻见效");
        }
    }

特殊需求:

如果有特殊需求,可传入两个泛型,重写onBindViewHolder搞事情:

        // ★泛型D:是Bean类型,如果有就传。  泛型B:是对应的xml Layout的Binding类
        mAdapter = new BaseBindingAdapter<DBSingleBean, ItemDbSingleBinding>(this, mDatas, R.layout.item_db_single) {
            @Override
            public void onBindViewHolder(BaseBindingVH<ItemDbSingleBinding> holder, int position) {
                //★super一定不要删除
                super.onBindViewHolder(holder, position);
                //如果有特殊需求,可传入两个泛型,重写onBindViewHolder搞事情。
                ItemDbSingleBinding binding = holder.getBinding();
                DBSingleBean data = mDatas.get(position);
            }
        };

2 多Item同种数据类型列表

一般是像IM那种列表,虽然Item不同,但是数据结构是同一个。用法,一句话~

效果如图:

用法:

  • 数据结构(JavaBean)需实现IBaseMulInterface接口,根据情况返回不同的layout。
  • 构造函数只需要传入context,datas.
    mAdapter = new BaseMulTypeBindingAdapter(this, mDatas);

复杂列表依然一句话。

public class MulTypeSingleBean extends BaseObservable implements IBaseMulInterface {
    private String avatar;
    private String name;
    private boolean receive;
    @Override
    public int getItemLayoutId() {
        if (isReceive()) {
            return R.layout.item_db_mul_1;
        } else {
            return R.layout.item_db_mul_2;
        }
    }
}

特殊需求:

如果有特殊需求,可传入数据结构的泛型,避免强转,重写onBindViewHolder()方法,但是Binding类 不可避免的需要强转了:

        mAdapter = new BaseMulTypeBindingAdapter<MulTypeSingleBean>(this, mDatas) {
            @Override
            public void onBindViewHolder(BaseBindingVH<ViewDataBinding> holder, int position) {
                super.onBindViewHolder(holder, position);
                //如果有特殊需求,可传入数据结构的泛型,避免强转
                MulTypeSingleBean data = mDatas.get(position);
                //Binding类 不可避免的需要强转了
                ViewDataBinding binding = holder.getBinding();
                switch (data.getItemLayoutId()) {
                    case R.layout.item_db_mul_1:
                        ItemDbMul1Binding itemDbMul1Binding = (ItemDbMul1Binding) binding;
                        break;
                    case R.layout.item_db_mul_2:
                        ItemDbMul2Binding itemDbMul2Binding = (ItemDbMul2Binding) binding;
                        break;
                }

            }
        };

3 多Item、多种数据类型列表

各大APP首页,Banner、列表、推荐混排,数据结构肯定不同,但是依然只要一句代码搞定Adapter!

效果如图:

用法:

  • 数据结构(JavaBean)需分别实现IBaseMulInterface接口,返回数据结构对应的layout。
  • 构造函数只需要传入context,datas.
    mAdapter = new BaseMulTypeBindingAdapter(this, mDatas);
public class MulTypeMulBean1 extends BaseObservable implements IBaseMulInterface {
    private String avatar;
    private String name;

    @Override
    public int getItemLayoutId() {
        return R.layout.item_db_mulbean_1;
    }
}
public class MulTypeMulBean2 extends BaseObservable implements IBaseMulInterface {
    private String background;

    @Override
    public int getItemLayoutId() {
        return R.layout.item_db_mulbean_2;
    }
}

特殊需求:

如果有特殊需求,重写onBindViewHolder()方法,但是数据结构 和 Binding类 都不可避免的需要强转了:

        mAdapter = new BaseMulTypeBindingAdapter(this, mDatas) {
            @Override
            public void onBindViewHolder(BaseBindingVH holder, int position) {
                super.onBindViewHolder(holder, position);
                //如果有特殊需求 重写onBindViewHolder方法
                // 数据结构 和 Binding类 都不可避免的需要强转了
                ViewDataBinding binding = holder.getBinding();
                switch (getItemViewType(position)) {
                    case R.layout.item_db_mul_1:
                        ItemDbMul1Binding itemDbMul1Binding = (ItemDbMul1Binding) binding;
                        MulTypeMulBean1 data1 = (MulTypeMulBean1) mDatas.get(position);
                        break;
                    case R.layout.item_db_mul_2:
                        ItemDbMul2Binding itemDbMul2Binding = (ItemDbMul2Binding) binding;
                        MulTypeMulBean2 data2 = (MulTypeMulBean2) mDatas.get(position);
                        break;
                }
            }
        };

4 不能忘了上文的ViewGroup呀

对上文封装的ViewGroup类型Adapter也提供DataBinding的支持。

效果如图:

当然还是流式布局搭配史上集成最叼侧滑菜单控件

用法:

和上文快速开发偷懒必备(一)一样,只是Adapter换成SingleBindingAdapter

    mAdapter = new SingleBindingAdapter<>(this, mDatas = iniDatas(), R.layout.item_db_flow_swipe);

如果需要设置点击事件:

    mAdapter.setItemPresenter(new ItemDelPresenter());

设计思路与实现

使用起来如此爽快,其实写起来也很简单。

注意类BaseBindingAdapterBaseMulTypeBindingAdapter都不是abstract的,这说明我们不需要重写任何方法

利用DataBinding,我们在BasexxxAdapter内部和xml分别做View的创建和数据绑定的工作。

UML类图

先简要概括

  • BaseBindingVH继承自RecyclerView.ViewHolder,持有T extends ViewDataBinding类型的mBinding变量。利用ViewDataBinding我们将不用再写任何ViewHolder
  • BaseBindingAdapter,继承自RecyclerView.Adapter,依赖BaseBindingVHonCreateViewHolder(ViewGroup parent, int viewType)方法返回BaseBindingVH作为ViewHolder

    内部持有三个重要变量:数据对应layout,数据集,Item点击事件处理类。数据对应layout会在onCreateViewHolder(ViewGroup parent, int viewType)用到。剩下两个变量在onBindViewHolder()用到。对外暴漏setItemPresenter(Object itemPresenter)供设置点击事件处理类。

  • IBaseMulInterface接口和快速开发偷懒必备(一)提到的一样,返回某个数据结构对应的layout,除此之外,本文还有一个十分tricky之处,利用返回的R.layout.itemxxxx作为ItemViewType,在BaseMulTypeBindingAdapter会用到。
  • BaseMulTypeBindingAdapter继承自BaseBindingAdapter,但是它不再关心mLayoutId变量,它利用IBaseMulInterface接口返回的R.layout.itemxxxx作为ItemViewType,这样在onCreateViewHolder(ViewGroup parent, int viewType)的时候,就可以直接用viewType构造出ItemView。不再依赖mLayoutId变量。这是一个我很得意的设计,我在优雅为RecyclerView增加HeaderView一文中,也曾用过这个方法。

BaseBindingVH

BaseBindingVH算是一个核心类,但是又十分简单。它继承自RecyclerView.ViewHolder,持有由泛型传入的T extends ViewDataBinding类型的mBinding变量。

唯一构造函数,需要一个T t变量,然后调用super()传入t.getRoot()完成itemView的赋值。同时对mBinding变量赋值。

对外暴漏getBinding()返回mBinding变量。

利用ViewDataBinding我们将不用再写任何ViewHolder

public class BaseBindingVH<T extends ViewDataBinding> extends RecyclerView.ViewHolder {
    protected final T mBinding;

    public BaseBindingVH(T t) {
        super(t.getRoot());
        mBinding = t;
    }

    public T getBinding() {
        return mBinding;
    }
}

BaseBindingAdapter

BaseBindingAdapter,继承自RecyclerView.Adapter,依赖BaseBindingVH,将BaseBindingVH作为泛型传给RecyclerView.Adapter

同时BaseBindingAdapter本身接受两个泛型,<D, B extends ViewDataBinding>

  • 泛型没有特殊需求可以不传
  • 泛型D:是Bean类型,如果有就传。
  • 泛型B:是对应的xml Layout的Binding类

传入不传入泛型的区别已经在第二节具体用法里进行了演示,不再赘述。

内部持有三个重要变量:

  • 数据对应layout int mLayoutId;
  • 数据集 List<D> mDatas;
  • Item点击事件处理类。Object ItemPresenter;

mLayoutIdmDatas都由构造函数传入,没啥好说的。

对外暴漏setItemPresenter(Object itemPresenter)供设置点击事件处理类ItemPresenter

ItemPresenterObject类型,这样才不care你set的Item点击事件处理类是什么鬼。

onCreateViewHolder(ViewGroup parent, int viewType)方法返回BaseBindingVH作为ViewHolder

mLayoutId会在onCreateViewHolder(ViewGroup parent, int viewType)用到,再根据泛型B强转成对应的ViewDataBinding

BaseBindingVH<B> holder = new BaseBindingVH<B>((B) DataBindingUtil.inflate(mInfalter, mLayoutId, parent, false));

会在onBindViewHolder()方法里,利用DataBinding动态绑定ViewDataBinding.setVariable(BR.itemP, ItemPresenter);为每个Item设置点击事件。

同时,数据也是同样在里面绑定的:setVariable(BR.data, mDatas.get(position))

重点代码如下:


public class BaseBindingAdapter<D, B extends ViewDataBinding> extends RecyclerView.Adapter<BaseBindingVH<B>> {
    protected Context mContext;
    protected int mLayoutId;
    protected List<D> mDatas;
    protected LayoutInflater mInfalter;
    //用于设置Item的事件Presenter
    protected Object ItemPresenter;

    public BaseBindingAdapter(Context mContext, List mDatas, int mLayoutId) {
        this.mContext = mContext;
        this.mLayoutId = mLayoutId;
        this.mDatas = mDatas;
        this.mInfalter = LayoutInflater.from(mContext);
    }

    @Override
    public BaseBindingVH<B> onCreateViewHolder(ViewGroup parent, int viewType) {
        BaseBindingVH<B> holder = new BaseBindingVH<B>((B) DataBindingUtil.inflate(mInfalter, mLayoutId, parent, false));
        onCreateViewHolder(holder);
        return holder;
    }

    /**
     * 如果需要给Vh设置监听器啥的 可以在这里
     *
     * @param holder
     */
    public void onCreateViewHolder(BaseBindingVH<B> holder) {

    }

    /**
     * 子类除了绑定数据,还要设置监听器等其他操作。
     * 可以重写这个方法,不要删掉super.onBindViewHolder(holder, position);
     *
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(BaseBindingVH<B> holder, int position) {
        holder.getBinding().setVariable(BR.data, mDatas.get(position));
        holder.getBinding().setVariable(BR.itemP, ItemPresenter);
        holder.getBinding().executePendingBindings();
    }
    /**
     * 用于设置Item的事件Presenter
     *
     * @param itemPresenter
     * @return
     */
    public BaseBindingAdapter setItemPresenter(Object itemPresenter) {
        ItemPresenter = itemPresenter;
        return this;
    }
}

BaseBindingAdapter内部也封装了如下方法,方便数据刷新,增删(定向刷新)调用:

    /**
     * 刷新数据,初始化数据
     *
     * @param list
     */
    public void setDatas(List<D> list) {
        if (this.mDatas != null) {
            if (null != list) {
                List<D> temp = new ArrayList<D>();
                temp.addAll(list);
                this.mDatas.clear();
                this.mDatas.addAll(temp);
            } else {
                this.mDatas.clear();
            }
        } else {
            this.mDatas = list;
        }
        notifyDataSetChanged();
    }

    /**
     * 删除一条数据
     * 会自动定向刷新
     *
     * @param i
     */
    public void remove(int i) {
        if (null != mDatas && mDatas.size() > i && i > -1) {
            mDatas.remove(i);
            notifyItemRemoved(i);
        }
    }

    /**
     * 添加一条数据 至队尾
     * 会自动定向刷新
     *
     * @param data
     */
    public void add(D data) {
        if (data != null && mDatas != null) {
            mDatas.add(data);
            notifyItemInserted(mDatas.size());
        }
    }

    /**
     * 在指定位置添加一条数据
     * 会自动定向刷新
     * <p>
     * 如果指定位置越界,则添加在队尾
     *
     * @param position
     * @param data
     */
    public void add(int position, D data) {
        if (data != null && mDatas != null) {
            if (mDatas.size() > position && position > -1) {
                mDatas.add(position, data);
                notifyItemInserted(position);
            } else {
                add(data);
            }
        }
    }

    /**
     * 加载更多数据
     *
     * @param list
     */
    public void addDatas(List<D> list) {
        if (null != list) {
            List<D> temp = new ArrayList<D>();
            temp.addAll(list);
            if (this.mDatas != null) {
                this.mDatas.addAll(temp);
            } else {
                this.mDatas = temp;
            }
            notifyDataSetChanged();
        }

    }

IBaseMulInterface接口

来点简单的.

IBaseMulInterface接口和快速开发偷懒必备(一)提到的一样,返回某个数据结构对应的layout.

除此之外,本文还有一个十分tricky之处,利用返回的R.layout.itemxxxx作为ItemViewType,在BaseMulTypeBindingAdapter会用到。

因为不同的R.layout.itemxxxx对于RecyclerView来说一定是不同的Item,

BaseMulTypeBindingAdapter

多种ItemType的Base类

BaseMulTypeBindingAdapter继承自BaseBindingAdapter,但是它不再关心mLayoutId变量。因此它传给父类的泛型B就是ViewDataBinding类本身。解释如下:

* 基类的泛型B:不用传,因为多种ItemType 肯定Layout长得不一样,那么Binding类也不一样,传入没有任何意义

  • 泛型T:多Item多Bean情况可以不传。如果只有一种Bean类型,可以传入Bean,实现IBaseMulInterface接口。

    或者传入IBaseMulInterface接口,可以拿到 getItemLayoutId(),

    但是通过getItemViewType(int position),一样。所以多Item多Bean建议不传。

    传入不传入泛型的区别已经在第二节具体用法里进行了演示,不再赘述。

getItemViewType()直接返回 IBaseMulInterface接口的返回值。

onCreateViewHolder(ViewGroup parent, int viewType)的时候,直接用viewType构建ViewDataBindingItemView)。不再依赖mLayoutId变量。

这是一个我很得意的设计,我在优雅为RecyclerView增加HeaderView一文中,也曾用过这个方法添加头部。

完整代码如下:

public class BaseMulTypeBindingAdapter<T extends IBaseMulInterface> extends BaseBindingAdapter<T, ViewDataBinding> {

    public BaseMulTypeBindingAdapter(Context mContext, List<T> mDatas) {
        super(mContext, mDatas);
    }

    @Override
    public int getItemViewType(int position) {
        return mDatas.get(position).getItemLayoutId();
    }

    @Override
    public BaseBindingVH<ViewDataBinding> onCreateViewHolder(ViewGroup parent, int viewType) {
        BaseBindingVH<ViewDataBinding> holder = new BaseBindingVH<ViewDataBinding>(DataBindingUtil.inflate(mInfalter, viewType, parent, false));
        onCreateViewHolder(holder);
        return holder;
    }
}

ViewGroup Adapter的实现

单item

继承SingleAdapter,增加ItemPresenter,在getView()完成View创建和绑定。

public class SingleBindingAdapter<D, B extends ViewDataBinding> extends SingleAdapter<D> {
    //用于设置Item的事件Presenter
    protected Object ItemPresenter;
    /**
     * 用于设置Item的事件Presenter
     *
     * @param itemPresenter
     * @return
     */
    public SingleBindingAdapter setItemPresenter(Object itemPresenter) {
        ItemPresenter = itemPresenter;
        return this;
    }

    public SingleBindingAdapter(Context context, List<D> datas, int itemLayoutId) {
        super(context, datas, itemLayoutId);
    }

    //重写利用DataBinding做
    @Override
    public View getView(ViewGroup parent, int pos, D data) {
        ViewDataBinding binding = DataBindingUtil.inflate(mInflater, mItemLayoutId, parent, false);
        View itemView = binding.getRoot();
        onBindView(parent, itemView, data, pos);
        binding.setVariable(BR.data, data);
        binding.setVariable(BR.itemP, ItemPresenter);
        return itemView;
    }

    //空实现即可,因为DataBinding的实现都是在xml里做
    @Override
    public void onBindView(ViewGroup parent, View itemView, D data, int pos) {

    }
}

多Item:

更简单了,继承SingleBindingAdapter。重写getView()即可。

public class MulTypeBindngAdapter<T extends IMulTypeHelper> extends SingleBindingAdapter<T, ViewDataBinding> {

    public MulTypeBindngAdapter(Context context, List<T> datas) {
        super(context, datas, -1);
    }

    //重写利用DataBinding做
    @Override
    public View getView(ViewGroup parent, int pos, T data) {
        ViewDataBinding binding = DataBindingUtil.inflate(mInflater, data.getItemLayoutId(), parent, false);
        View itemView = binding.getRoot();
        onBindView(parent, itemView, data, pos);
        binding.setVariable(BR.data, data);
        binding.setVariable(BR.itemP, ItemPresenter);
        return itemView;
    }
}

总结

代码传送门:喜欢的话,随手点个star。多谢

https://github.com/mcxtzhang/all-base-adapter

本文利用DataBindingViewDataBinding直接略去写ViewHolder

利用Object类型的ItemPresenter,兼容解决了点击事件的设置。

最得意的设计,还是利用R.layout.xxxx这些布局文件int类型的的RID,作为ItemViewType,一箭双雕。

DataBinding很强,希望大家快点拥抱它。

to do list

  • ViewGroup Adapter 考虑加入复用缓存池
  • ViewGroup Adapter ,考虑替换onBindView()ItemView->通用的ViewHolder,这样可以少写一些findViewById()代码
  • 整合DataBinding 的通用Adapter入库。
  • 完善 RecyclerView、ListView的通用Adapter,支持多种ItemViewType。
  • 加入一些自定义ViewGroup入库,例如流式布局,九宫格,Banner轮播图。

转载请标明出处:

http://blog.csdn.net/zxt0601/article/details/53618694

本文出自:【张旭童的博客】(http://blog.csdn.net/zxt0601)

代码传送门:喜欢的话,随手点个star。多谢

https://github.com/mcxtzhang/all-base-adapter

时间: 2024-12-25 10:26:37

【Android】快速开发偷懒必备(二) 支持DataBinding啦~爽炸,一行实现花式列表的相关文章

【Android】快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup

转载请标明出处: http://blog.csdn.net/zxt0601/article/details/53576092 本文出自:[张旭童的博客](http://blog.csdn.net/zxt0601) 代码传送门:喜欢的话,随手点个star.多谢 https://github.com/mcxtzhang/all-base-adapter 概述 开发中,经常会用到动态在ScrollView.LinearLayout里addView的事,尤其是ItemView一样时,每次都要写一大堆代码

Android 快速开发系列 打造万能的ListView GridView 适配器

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写得最多的就是ListView,GridView的适配器吧,记得以前开发一同事开发项目,一个项目下来基本就一直在写ListView的Adapter都快吐了~~~对于Adapter一般都继承BaseAdapter复写几个方法,getView里面使用ViewHolder模式,其实大部分的代码基本都是类似的

使用 CodeIgniter 框架快速开发 PHP 应用(二)

原文:使用 CodeIgniter 框架快速开发 PHP 应用(二) 二分钟: 建立一个 CodeIgniter 网站 用CI建一个网站很容易. 这一章很短,解释了用CI制作网站时发生了些什么,哪些文件被创建,让我们来瞧一瞧: . 创建网站需要什么软件? . 安装 CI 文件: 一个简单的下载和解压缩操作 . CI 的基本设置: 有哪些文件夹及它们是如何组织的 . CI 安装时默认的控制器和视图 . 一些简单的修改来演示CI如何运作 准备知识 CodeIgniter 有较好的版本兼容性. 它工作

UltimateAndroid快速开发框架简介与教程(也是一套Android快速开发的教程)

UltimateAndroid是一套集成了许多现有优秀的Android开源类库并将之组合成一个整体的Android快速开发框架. github地址:https://github.com/cymcsg/UltimateAndroid 框架目前主要包含的功能有View Injection,ORM,异步网络请求和图片加载,自动化脚本测试,磁盘LRU等功能.同时提供了类似于TripleDes.Webview快速设置.Md5处理.String处理,Https处理等常用工具类,还有多种UI控件效果.并且这些

Android快速开发不可或缺的11个工具类(下载)

功能分类:工具     支持平台:Android     运行环境:Eclipse 开发语言:Java      开发工具:Eclipse         源码大小:11.45KB 下载地址:http://sina.lt/zx9   源码简介 Android快速开发不可或缺的11个辅助类,其中10个来自张鸿洋的博客,1个是我平时积攒的,复制粘贴到你的项目里,添加上包名就可以直接使用,能提高开发速度.

Android 自定义控件开发入门(二)

上一次我们讲了一堆实现自定义控件的理论基础,列举了View类一些可以重写的方法,我们对这些方法的重写是我们继承View类来派生自定义控件的关键 我通过一个最简单的例子给大家展示了这一个过程,无论是多么复杂的自定义控件,思路总是这样子的,但是因为我们仅仅重写了onDraw方法使得大家觉得怪怪的,作为一个控件,我们居然还要为了他的实现为其增加麻烦的监听,这就不能叫做控件了. 下面再给大家介绍一个经常重写的方法法:publicboolean onTouchEvent (MotionEvent even

Android快速开发不可或缺的11个工具类

Android快速开发不可或缺的11个辅助类,其中10个来自张鸿洋的博客,1个是我平时积攒的,复制粘贴到你的项目里,添加上包名就可以直接使用,能提高开发速度. 下载地址:http://www.dwz.cn/AHL17 包含文件:

【读书笔记《C# 开发实战1200例》】1.3 快速开发项目必备

009.为项目添加DLL文件引用 1.选中项目单击右键,选择“添加引用” PS:DLL文件是一种最常用的第三方组件表示形式,在 C# 中引用 DLL 文件后,可以直接使用其中编写好的方法来实现相应的功能,从而提高程序的开发效率. 010.为项目添加已有类 1.同理,右键“添加” - “现有项” PS:已知类就是已经编好的类,类就是面向对象编程的核心,它可以封装数据成员.函数成员和其他类等信息, C# 中使用关键字 class 来声明类. 011.为项目添加第三方控件 1.新建Windows窗体应

Android流媒体开发之路二:NDK开发Android端RTMP直播推流程序

NDK开发Android端RTMP直播推流程序 经过一番折腾,成功把RTMP直播推流代码,通过NDK交叉编译的方式,移植到了Android下,从而实现了Android端采集摄像头和麦克缝数据,然后进行h264视频编码和aac音频编码,并发送到RTMP服务器,从而实现Android摄像头直播.程序名为NdkRtmpEncoder,在这里把整个过程,和大体框架介绍一下,算是给需要的人引路. 开发思路 首先,为什么要用NDK来做,因为自己之前就已经实现过RTMP推流.RTMP播放.RTSP转码等等各种