Android常見基類封裝

前段時間一直在忙找工作的事,好久沒有寫博客了,最近在學(xué)習(xí)一個實戰(zhàn)項目http://coding.imooc.com/class/evaluation/100.html,講到了基類的封裝,故在此記錄一下。主要涉及到Activity,Fragment和RecyclerView的適配器的封裝。

一、Activity基類的封裝

由于都有詳細的注釋,并且代碼簡單,就不再解釋了,文中使用了ButterKnife。

public abstract class Activity extends AppCompatActivity {
    protected Unbinder mUnbinder;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在界面初始化之前初始化窗口
        initWindows();
        if (initArgs(getIntent().getExtras())) {
            int layoutId = getContentLayoutId();
            setContentView(layoutId);
            initWidget();
            initData();
        } else {
            finish();
        }
    }

    /**
     * 初始化窗口
     */
    protected void initWindows(){

    }
    /**
     * 初始化參數(shù)
     * @param bundle 需要初始化的參數(shù)
     * @return 如果參數(shù)正確返回true,錯誤返回false
     */
    protected boolean initArgs(Bundle bundle) {
        return true;
    }

    /**
     * 獲得當前界面的資源文件Id
     * @return 界面的資源文件Id
     */
    protected abstract int getContentLayoutId();

    /**
     * 初始化控件
     */
    protected void initWidget() {
        mUnbinder = ButterKnife.bind(this);
    }

    /**
     * 初始化數(shù)據(jù)
     */
    protected void initData() {

    }

    @Override
    public boolean onSupportNavigateUp() {
        //當點擊界面導(dǎo)航返回時,finish當前界面
        finish();
        return super.onSupportNavigateUp();
    }

    @Override
    public void onBackPressed() {
        //獲得當前Activity的所有Fragment
        @SuppressWarnings("RestrictedApi")
        List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
        if (fragmentList != null && fragmentList.size() > 0){
            for (Fragment fragment : fragmentList) {
                //是否是我們自定義的Fragment
                if (fragment instanceof cn.codekong.common.app.Fragment){
                    if (((cn.codekong.common.app.Fragment)fragment).onBackPressed()){
                        //Fragment處理了返回事件
                        return;
                    }
                }
            }
        }
        super.onBackPressed();
        finish();
    }
}

二、Fragment基類的封裝

public abstract class Fragment extends android.support.v4.app.Fragment {
    protected View mRoot;
    protected Unbinder mRootUnbinder;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        initArgs(getArguments());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (mRoot == null){
            int layoutId = getContentLayoutId();
            //初始化當前的根布局,但是不在創(chuàng)建時就添加到container里面
            View root = inflater.inflate(layoutId, container, false);
            initWidget(root);
            mRoot = root;
        }else {
            if (mRoot.getParent() != null){
                //把當前的根布局從其父控件中移除
                ((ViewGroup)mRoot.getParent()).removeView(mRoot);
            }
        }
        return mRoot;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //當View創(chuàng)建完成后初始化數(shù)據(jù)
        initData();
    }

    /**
     * 初始化參數(shù)
     * @param bundle 需要初始化的參數(shù)
     */
    protected void initArgs(Bundle bundle) {
    }

    /**
     * 獲得當前界面的資源文件Id
     *
     * @return 資源文件Id
     */
    protected abstract int getContentLayoutId();

    /**
     * 初始化控件
     */
    protected void initWidget(View root) {
        mRootUnbinder = ButterKnife.bind(this, root);
    }

    /**
     * 初始化數(shù)據(jù)
     */
    protected void initData() {

    }

    /**
     * 返回按鍵觸發(fā)時調(diào)用
     * @return 返回true代表自己處理返回邏輯,Activity不用處理
     * 返回false代表沒有處理邏輯,交由Activity處理
     */
    public boolean onBackPressed(){
        return false;
    }
}

三、RecyclerView適配器基類的封裝

public abstract class RecyclerAdapter<Data> extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder<Data>>
        implements View.OnClickListener, View.OnLongClickListener, AdapetrCallback<Data> {
    private final List<Data> mDataList;
    private AdapterListener<Data> mAdapterListener;

    /**
     * 構(gòu)造函數(shù)
     */
    public RecyclerAdapter() {
        this(null);
    }

    public RecyclerAdapter(AdapterListener<Data> listener) {
        this(new ArrayList<Data>(), listener);
    }

    public RecyclerAdapter(List<Data> dataList, AdapterListener<Data> listener) {
        this.mDataList = dataList;
        this.mAdapterListener = listener;
    }


    /**
     * 創(chuàng)建一個ViewHolder
     *
     * @param parent   RecyclerView
     * @param viewType 界面的類型,約定為xml布局的Id
     * @return
     */
    @Override
    public ViewHolder<Data> onCreateViewHolder(ViewGroup parent, int viewType) {
        //將xml布局初始化為View
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View root = inflater.inflate(viewType, parent, false);
        ViewHolder<Data> holder = onCreateViewHolder(root, viewType);
        //設(shè)置View的Tag將View和Holder進行關(guān)聯(lián)
        root.setTag(R.id.tag_recycler_holder, holder);
        //設(shè)置事件點擊
        root.setOnClickListener(this);
        root.setOnLongClickListener(this);
        //進行界面注解綁定
        holder.mUnbinder = ButterKnife.bind(holder, root);
        //綁定callback
        holder.mCallback = this;
        return holder;
    }


    /**
     * 獲得一個新的ViewHolder
     *
     * @param root     根布局
     * @param viewType 布局類型,其實就是xml的Id
     * @return ViewHolder
     */
    protected abstract ViewHolder<Data> onCreateViewHolder(View root, int viewType);

    /**
     * 復(fù)寫默認的布局類型返回
     *
     * @param position 坐標
     * @return 重寫后返回的是xml文件的Id
     */
    @Override
    public int getItemViewType(int position) {
        return getItemViewType(position, mDataList.get(position));
    }

    /**
     * 得到布局的類型
     *
     * @param position 坐標
     * @param data     當前的數(shù)據(jù)
     * @return xml文件的Id, 用于創(chuàng)建ViewHolder
     */
    @LayoutRes
    protected abstract int getItemViewType(int position, Data data);

    /**
     * 綁定數(shù)據(jù)到Holder上
     *
     * @param holder   ViewHolder
     * @param position 坐標
     */
    @Override
    public void onBindViewHolder(ViewHolder<Data> holder, int position) {
        //獲得需要綁定的數(shù)據(jù)
        Data data = mDataList.get(position);
        //觸發(fā)綁定方法
        holder.bind(data);
    }

    /**
     * 得到當前集合的數(shù)據(jù)量
     *
     * @return
     */
    @Override
    public int getItemCount() {
        return mDataList.size();
    }

    /**
     * 插入一條數(shù)據(jù)并通知插入更新
     *
     * @param data
     */
    public void add(Data data) {
        mDataList.add(data);
        notifyItemInserted(mDataList.size() - 1);
    }

    /**
     * 插入多條數(shù)據(jù),并通知這一段集合更新
     *
     * @param dataList
     */
    public void add(Data... dataList) {
        if (dataList != null && dataList.length > 0) {
            int startPos = mDataList.size();
            Collections.addAll(mDataList, dataList);
            notifyItemRangeInserted(startPos, dataList.length);
        }
    }

    /**
     * 插入多條數(shù)據(jù),并通知這一段集合更新
     *
     * @param dataList
     */
    public void add(Collection<Data> dataList) {
        if (dataList != null && dataList.size() > 0) {
            int startPos = mDataList.size();
            mDataList.addAll(dataList);
            notifyItemRangeInserted(startPos, dataList.size());
        }
    }

    /**
     * 刪除操作
     */
    public void clear() {
        mDataList.clear();
        notifyDataSetChanged();
    }

    /**
     * 替換為一個新的集合,其中包括清空
     *
     * @param dataList
     */
    public void replace(Collection<Data> dataList) {
        mDataList.clear();
        if (dataList == null || dataList.size() == 0) {
            return;
        }
        mDataList.addAll(dataList);
        notifyDataSetChanged();
    }

    @Override
    public void onClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (mAdapterListener != null) {
            //得到ViewHolder當前對應(yīng)的適配器中的坐標
            int pos = viewHolder.getAdapterPosition();
            //回調(diào)方法
            mAdapterListener.onItemClick(viewHolder, mDataList.get(pos));
        }
    }

    @Override
    public boolean onLongClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (mAdapterListener != null) {
            //得到ViewHolder當前對應(yīng)的適配器中的坐標
            int pos = viewHolder.getAdapterPosition();
            //回調(diào)方法
            mAdapterListener.onItemLongClick(viewHolder, mDataList.get(pos));
            return true;
        }
        return false;
    }

    /**
     * 設(shè)置監(jiān)聽器
     *
     * @param adapterListener
     */
    public void setAdapterListener(AdapterListener<Data> adapterListener) {
        this.mAdapterListener = adapterListener;
    }

    /**
     * 自定義監(jiān)聽器
     *
     * @param <Data> 泛型
     */
    public interface AdapterListener<Data> {
        //當Item點擊時出發(fā)
        void onItemClick(RecyclerAdapter.ViewHolder holder, Data data);

        //當Item長按時觸發(fā)
        void onItemLongClick(RecyclerAdapter.ViewHolder holder, Data data);
    }

    /**
     * 自定義的ViewHolder
     *
     * @param <Data> 泛型類型
     */
    public static abstract class ViewHolder<Data> extends RecyclerView.ViewHolder {
        protected Data mData;
        private Unbinder mUnbinder;
        private AdapetrCallback<Data> mCallback;

        public ViewHolder(View itemView) {
            super(itemView);
        }

        /**
         * 用于綁定數(shù)據(jù)
         *
         * @param data 需要綁定的數(shù)據(jù)
         */
        void bind(Data data) {
            this.mData = data;
            onBind(data);
        }

        /**
         * 當數(shù)據(jù)綁定時進行回調(diào),必須復(fù)寫
         *
         * @param data 需要綁定的數(shù)據(jù)
         */
        protected abstract void onBind(Data data);

        /**
         * holder自己對自己的Data進行更新
         *
         * @param data 需要更新的數(shù)據(jù)
         */
        public void updateData(Data data) {
            if (mCallback != null) {
                mCallback.update(data, this);
            }
        }
    }
}
public interface AdapetrCallback<Data> {
    void update(Data data, RecyclerAdapter.ViewHolder<Data> holder);
}

四、后記

基類的封裝可以有效地提高代碼的復(fù)用性,減少代碼了,希望上面的分享可以幫助到需要的人。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容