Android圖解建立外部lib庫及自定義View

阿策~發表於2018-11-14

      隨著外掛化/元件化的快速發展,現在大部分的專案開發中都會提取公共的程式碼製作成 Library module,根據具體的業務需求進行拆分。小菜也學習一下如何拆分 lib 包,實際操作很簡單,整理一下操作步驟。

拆分建立 Library

(1) 在當前 Project 下,File -> New Module,選擇 Android Library,進行下一步;

(2) 設定具體的 Library/Module/Package 等名稱,注意:Module 名稱與 Library 相匹配預設為小寫,需要的話手動調整,進行下一步;

(3) 此時在當前 Project 中就已經建立好 Library

(4) 在當前 Projectsettings.gradle 中就會自動生成建立的 Module

Tips: :myview 中的 : 代表的與 app 同級目錄下的 Module

  1. 在當前 appbuild.gradledependencies{} 中新增 implementation project(`:myview`) 即可正常接入。

自定義 View

      小菜在新建的 Library 中新增一個自定義按鈕,可以新增配置圖示和文字以及背景樣式。因為只是為了測試 Library Module,所以功能很簡單,實現方式也很簡單,只是幾個基本控制元件的組合。小菜只是簡單的整理一下。

  1. 新建一個 MyView 繼承自 RelativeLayout,實現基本的構造方法;
  2. 在構造方法中實現對佈局的新增,控制元件的繫結以及一些基本的 setXX 方法;
  3. 至此 MyView 就可以應用,但所有但屬性都需要通過 setXX 方法來設定;這當然是不合理的,於是小菜新建一個 attrs 檔案,在資原始檔中設定基本的樣式,並在 MyViewobtainAttributes 方法中逐一繫結即可;
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
    <declare-styleable name="my_view" tools:ignore="MissingDefaultResource">
        <!-- 中間文字顏色 -->
        <attr name="tv_color" format="color" />
        <!-- 中間文字顯隱性 -->
        <attr name="tv_show" format="boolean" />
        <!-- 中間文字內容 -->
        <attr name="tv_str" format="string" />
        <!-- 中間文字大小 -->
        <attr name="tv_size" format="float" />
        <!-- 右側文字顏色 -->
        <attr name="right_tv_color" format="color" />
        <!-- 右側文字顯隱性 -->
        <attr name="right_tv_show" format="boolean" />
        <!-- 右側文字內容 -->
        <attr name="right_tv_str" format="string" />
        <!-- 右側文字大小 -->
        <attr name="right_tv_size" format="float" />
        <!-- 整體背景顏色 -->
        <attr name="bg_color" format="color" />
        <!-- 整體邊框顏色 -->
        <attr name="strok_color" format="color" />
        <!-- 整體邊框圓角 -->
        <attr name="bg_radius" format="float" />
        <!-- 中間圖片顯隱性 -->
        <attr name="iv_show" format="boolean" />
        <!-- 中間圖片資源 -->
        <attr name="iv_src" format="reference" />
    </declare-styleable>
</resources>
  1. 至此,MyView 自定義按鈕以及完成,在 app 中也是正常呼叫即可。
public class MyView extends RelativeLayout {

    private Context mContext;
    private RelativeLayout mRlay;
    private ImageView mIv;
    private TextView mTv, mRightTv;
    GradientDrawable drawable = new GradientDrawable();

    int mTvColor, mRightTvColor, mRlayBgColor, mStrokeColor, mIvSrc;
    boolean isTvShow, isRightTvShow, isIvShow;
    float mTvSize, mRightTvSize, mRadiusSize;
    String mTvStr, mRightTvStr;

    public MyView(Context context) {
        super(context);
        mContext = context;
        initView();
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
        obtainAttributes(context,attrs);
    }

    private void initView() {
        LayoutInflater.from(mContext).inflate(R.layout.my_view_btn, this,true);
        mRlay = findViewById(R.id.my_view_rly);
        mIv = findViewById(R.id.my_view_iv);
        mTv = findViewById(R.id.my_view_tv);
        mRightTv = findViewById(R.id.my_view_rtv);
    }

    private void obtainAttributes(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.my_view);

        mTvColor = ta.getColor(R.styleable.my_view_tv_color, Color.BLACK);
        mTv.setTextColor(mTvColor);
        mRightTvColor = ta.getColor(R.styleable.my_view_right_tv_color, Color.BLACK);
        mRightTv.setTextColor(mRightTvColor);
        mRlayBgColor = ta.getColor(R.styleable.my_view_bg_color, Color.WHITE);
        mRlay.setBackgroundColor(mRlayBgColor);
        mStrokeColor = ta.getColor(R.styleable.my_view_strok_color, Color.BLACK);
        isIvShow = ta.getBoolean(R.styleable.my_view_iv_show, true);
        mIv.setVisibility(isIvShow?View.VISIBLE:View.GONE);
        isRightTvShow = ta.getBoolean(R.styleable.my_view_right_tv_show, true);
        mRightTv.setVisibility(isRightTvShow?View.VISIBLE:View.GONE);
        isTvShow = ta.getBoolean(R.styleable.my_view_tv_show, true);
        mTv.setVisibility(isTvShow?View.VISIBLE:View.GONE);
        mTvSize = ta.getFloat(R.styleable.my_view_tv_size, 16.0f);
        mTv.setTextSize(mTvSize);
        mRightTvSize = ta.getFloat(R.styleable.my_view_right_tv_size, 14.0f);
        mRightTv.setTextSize(mRightTvSize);
        mRadiusSize = ta.getFloat(R.styleable.my_view_bg_color, 80.0f);
        drawable = (GradientDrawable) getResources().getDrawable(R.drawable.user_login_corner_qq);
        drawable.setCornerRadius(mRadiusSize);
        drawable.setStroke(1, mStrokeColor);
        drawable.setColor(mRlayBgColor);
        mRlay.setBackground(drawable);
        mTvStr = ta.getString(R.styleable.my_view_tv_str);
        mTv.setText(mTvStr);
        mRightTvStr = ta.getString(R.styleable.my_view_right_tv_str);
        mRightTv.setText(mRightTvStr);
        mIvSrc = ta.getResourceId(R.styleable.my_view_iv_src, R.mipmap.user_login_icon_qq);
        mIv.setImageResource(mIvSrc);

        ta.recycle();
    }

    public void setMyViewTv(String textStr) {
        mTv.setText(textStr);
    }

    public void setMyViewTvColor(int color) {
        mTv.setTextColor(color);
    }

    public void setMyViewTvSize(float size) {
        mTv.setTextSize(size);
    }

    public void isMyViewTvShow(boolean state) {
        mTv.setVisibility(state ? View.VISIBLE : View.GONE);
    }

    public void setMyViewIv(Drawable drawable) {
        mIv.setImageDrawable(drawable);
    }

    public void isMyViewIvShow(boolean state) {
        mIv.setVisibility(state ? View.VISIBLE : View.GONE);
    }

    public void isMyViewRightTvShow(boolean state) {
        mRightTv.setVisibility(state ? View.VISIBLE : View.GONE);
    }

    public void setMyViewRightTvText(String textStr) {
        mRightTv.setText(textStr);
    }

    public void setMyViewRightTvSize(float size) {
        mRightTv.setTextSize(size);
    }

    public void setMyViewRightTvColor(int color) {
        mRightTv.setTextColor(color);
    }

    public void setMyViewBgColor(int color) {
        drawable.setColor(color);
        mRlay.setBackground(drawable);
    }

    public void setMyViewBgRadius(float radius) {
        drawable.setCornerRadius(radius);
        mRlay.setBackground(drawable);
    }

    public void setMyViewBgStrokeColor(int color) {
        drawable.setStroke(1, color);
        mRlay.setBackground(drawable);
    }

    public void setMyViewBgDrawable(Drawable drawable) {
        mRlay.setBackground(drawable);
    }
}

      Tips: attrs.xml 中如果需要用到資原始檔,可以使用 format=”reference”,代表某一個資源ID。


      小菜也是初步嘗試,有不對的地方煩請提醒。以下是小菜公眾號,歡迎閒來吐槽~
公眾號.jpg


相關文章