制作自己的 GitHub 依赖库——俗称“造轮子”
一、步骤
- 在 Android Library 中制作简易的自定义布局
- 本地测试
- 上传 GitHub
- 生成 release 版本
- 添加到 JitPack
- 依赖使用测试
二、效果图
三、开发
(一)在Android Library中制作简易的自定义布局
- 在 Android 工程中新建 Module
- 新建 Android Library
- 文件位置概览
- Library 开发之绘制自定义布局(setting_item_bar.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="wrap_content"
android:id="@+id/relative_layout"
android:background="@color/nav_bar_background"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<ImageView
android:id="@+id/icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_margin="5dp"
android:src="@drawable/setting" />
<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:gravity="center_vertical"
android:layout_marginRight="5dp"
android:layout_marginLeft="16dp"
android:layout_toRightOf="@id/icon"
android:layout_centerInParent="true"
android:text="@string/nav_bar_title_default"
android:textColor="#292929"
android:textSize="18sp" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:gravity="center_vertical"
android:layout_marginRight="8dp"
android:layout_marginLeft="5dp"
android:layout_toLeftOf="@id/forward"
android:layout_centerInParent="true"
android:text="@string/nav_bar_info_default"
android:textSize="16sp"/>
<ImageView
android:id="@+id/forward"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_margin="5dp"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:src="@drawable/forward" />
</RelativeLayout>
- Library 开发之自定义布局属性(attrs.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
一个属性集合,外层的name是属性集合名称,
内层的name则是属性的名称,format则是属性的值的类型
-->
<declare-styleable name="SettingItemBar">
<!-- TextView的内容以及可见性 -->
<attr name="title_text" format="string|reference" />
<attr name="title_text_visibility">
<enum name="visible" value="0" />
<enum name="invisible" value="4" />
<enum name="gone" value="8" />
</attr>
<!-- TextView的内容以及可见性 -->
<attr name="info_text" format="string|reference" />
<attr name="info_text_visibility">
<enum name="visible" value="0" />
<enum name="invisible" value="4" />
<enum name="gone" value="8" />
</attr>
<!-- ImageView的内容以及可见性 -->
<attr name="icon_iv" format="reference" />
<attr name="icon_iv_visibility">
<enum name="visible" value="0" />
<enum name="invisible" value="4" />
<enum name="gone" value="8" />
</attr>
<!-- ImageView的内容以及可见性 -->
<attr name="forward_iv" format="reference" />
<attr name="forward_iv_visibility">
<enum name="visible" value="0" />
<enum name="invisible" value="4" />
<enum name="gone" value="8" />
</attr>
<!-- 自定义布局的背景颜色 -->
<attr name="background_color" format="color" />
</declare-styleable>
</resources>
- 编写控制自定义布局的 java 类实现对其控制。(SettingItemBar.java)
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class SettingItemBar extends RelativeLayout {
RelativeLayout mRelativeLayout;//布局
private ImageView mIconIV;//最左侧图标
private int icon;//图标对应资源id
private int iconVisibility;//图标可见性
private String titleText;//标题文字
private TextView mTitleTextTV;//标题文字对应的TextView
private int titleTextVisibility;//标题可见性
private String infoText;//信息文字
private TextView mInfoTextTV;//信息文字对应的TextView
private int infoTextVisibility;//信息可见性
private ImageView mForwardIV;//最左侧图标
private int forward;//最左侧图标对应资源id
private int forwardVisibility;//最左侧图标可见性
private int backgroundColor;//背景颜色
/*
构造函数,参数一:上下文;参数二:属性集
*/
public SettingItemBar(Context context, AttributeSet attrs){
super(context,attrs);
//加载自定义布局
LayoutInflater.from(context).inflate(R.layout.setting_item_bar,this);
//实例化组件
mIconIV = (ImageView) findViewById(R.id.icon);
mForwardIV = (ImageView) findViewById(R.id.forward);
mTitleTextTV = (TextView)findViewById(R.id.title_text);
mInfoTextTV = (TextView)findViewById(R.id.text);
mRelativeLayout = (RelativeLayout)findViewById(R.id.relative_layout);
/*
每一个属性集合编译之后都会对应一个styleable对象,
通过styleable对象获取TypedArray typedArray,然后通过键值对获取属性值。
R.styleable.SettingsItemLayout,SettingsItemLayout对应attrs里面属性集的名称而不是本类的类名
*/
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SettingItemBar);
if (typedArray != null) {
titleText = typedArray.getString(R.styleable.SettingItemBar_title_text);
titleTextVisibility = typedArray.getInt(R.styleable.SettingItemBar_title_text_visibility,0);
infoText = typedArray.getString(R.styleable.SettingItemBar_info_text);
infoTextVisibility = typedArray.getInt(R.styleable.SettingItemBar_info_text_visibility,0);
icon = typedArray.getResourceId(R.styleable.SettingItemBar_icon_iv,R.drawable.setting);
iconVisibility = typedArray.getInt(R.styleable.SettingItemBar_icon_iv_visibility,0);
forward = typedArray.getResourceId(R.styleable.SettingItemBar_forward_iv,R.drawable.forward);
forwardVisibility = typedArray.getInt(R.styleable.SettingItemBar_forward_iv_visibility,0);
backgroundColor = typedArray.getColor(R.styleable.SettingItemBar_background_color,getResources().getColor(R.color.nav_bar_background));
typedArray.recycle();
}
//将自定义的属性值设置到组件上
mTitleTextTV.setText(titleText);
mTitleTextTV.setVisibility(titleTextVisibility);
mInfoTextTV.setText(infoText);
mInfoTextTV.setVisibility(infoTextVisibility);
mIconIV.setImageResource(icon);
mIconIV.setVisibility(iconVisibility);
mForwardIV.setImageResource(forward);
mForwardIV.setVisibility(forwardVisibility);
mRelativeLayout.setBackgroundColor(backgroundColor);
//点击事件
mIconIV.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
iconOICL.OnClick();
}
});
mTitleTextTV.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
titleOICL.OnClick();
}
});
mInfoTextTV.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
infoOICL.OnClick();
}
});
mForwardIV.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
forwardOICL.OnClick();
}
});
}
//设置标题内容及颜色,参数为字符串或者资源id或者颜色
public void setTitleText(String titleText){
mTitleTextTV.setText(titleText);
}
public void setTitleText(int titleText){
mTitleTextTV.setText(titleText);
}
public void setTitleTextColor(int color){
mTitleTextTV.setTextColor(color);
}
//设置标题文本样式 0 normal 1 bold 2 italic
public void setTitleStyle(int style){
switch (style){
case 0:
mTitleTextTV.setTypeface(Typeface.DEFAULT,Typeface.NORMAL);
break;
case 1:
mTitleTextTV.setTypeface(Typeface.DEFAULT,Typeface.BOLD);
break;
case 2:
mTitleTextTV.setTypeface(Typeface.DEFAULT,Typeface.ITALIC);
break;
default:
break;
}
}
//设置信息内容及颜色,参数为字符串或者资源id或者颜色
public void setInfoText(String infoText){
mInfoTextTV.setText(infoText);
}
public void setInfoText(int infoText){
mInfoTextTV.setText(infoText);
}
public void setInfoTextColor(int color){
mInfoTextTV.setTextColor(color);
}
//设置信息文本样式 0 normal 1 bold 2 italic
public void setInfoStyle(int style){
switch (style){
case 0:
mInfoTextTV.setTypeface(Typeface.DEFAULT,Typeface.NORMAL);
break;
case 1:
mInfoTextTV.setTypeface(Typeface.DEFAULT,Typeface.BOLD);
break;
case 2:
mInfoTextTV.setTypeface(Typeface.DEFAULT,Typeface.ITALIC);
break;
default:
break;
}
}
//设置两侧图标及布局背景颜色
public void setIconIV(int id){
mIconIV.setImageResource(id);
}
public void setForwardIV(int id){
mForwardIV.setImageResource(id);
}
public void setBackground(int color){
mRelativeLayout.setBackgroundColor(color);
}
//设置组件的可见性 8 GONE 4 INVISIBLE 0 VISIBLE
public void setIconIVVisibility(int flag){
switch (flag){
case 8:
mIconIV.setVisibility(GONE);
break;
case 4:
mIconIV.setVisibility(INVISIBLE);
break;
case 0:
mIconIV.setVisibility(VISIBLE);
break;
default:
break;
}
}
public void setForwardIVVisibility(int flag){
switch (flag){
case 8:
mForwardIV.setVisibility(GONE);
break;
case 4:
mForwardIV.setVisibility(INVISIBLE);
break;
case 0:
mForwardIV.setVisibility(VISIBLE);
break;
default:
break;
}
}
public void setTitleTextTVVisibility(int flag){
switch (flag){
case 8:
mTitleTextTV.setVisibility(GONE);
break;
case 4:
mTitleTextTV.setVisibility(INVISIBLE);
break;
case 0:
mTitleTextTV.setVisibility(VISIBLE);
break;
default:
break;
}
}
public void setInfoTextTVVisibility(int flag){
switch (flag){
case 8:
mInfoTextTV.setVisibility(GONE);
break;
case 4:
mInfoTextTV.setVisibility(INVISIBLE);
break;
case 0:
mInfoTextTV.setVisibility(VISIBLE);
break;
default:
break;
}
}
//定义点击事件接口
public interface OnItemClickListener{
void OnClick();
}
//实例化
private OnItemClickListener iconOICL = new OnItemClickListener() {
@Override
public void OnClick() {
}
};
private OnItemClickListener titleOICL = new OnItemClickListener() {
@Override
public void OnClick() {
}
};
private OnItemClickListener infoOICL = new OnItemClickListener() {
@Override
public void OnClick() {
}
};
private OnItemClickListener forwardOICL = new OnItemClickListener() {
@Override
public void OnClick() {
}
};
//设置点击事件的回调 0 左侧图标 1 标题 2 信息 3 右侧图标
public void setOnItemClickListener(OnItemClickListener on,int type){
switch (type){
case 0:
iconOICL = on;
break;
case 1:
titleOICL = on;
break;
case 2:
infoOICL = on;
break;
case 3:
forwardOICL = on;
break;
default:
break;
}
}
}
(二)本地测试
- 在 app 下的 build.gradle 添加本地库依赖
dependencies {
...
implementation project(':settingitembarlibrary')
}
- 在 activity_main.xml 中使用该自定义的布局
<com.hzf.nicholas.settingitembarlibrary.SettingItemBar
android:id="@+id/setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hzf:forward_iv="@drawable/about"
hzf:info_text="@string/nav_bar_info_default"
hzf:title_text="@string/nav_bar_title_default">
</com.hzf.nicholas.settingitembarlibrary.SettingItemBar>
- 在 MainActivity.java 中控制
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.hzf.nicholas.settingitembarlibrary.SettingItemBar;
public class MainActivity extends AppCompatActivity {
//声明自定义布局
SettingItemBar mSettingItemBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定实例
mSettingItemBar = findViewById(R.id.setting);
//动态设置信息
mSettingItemBar.setTitleText("NICHOLAS.HZF");
mSettingItemBar.setInfoTextColor(Color.parseColor("#ff0000"));
mSettingItemBar.setTitleStyle(2);
mSettingItemBar.setInfoTextTVVisibility(8);
//编写点击事件
mSettingItemBar.setOnItemClickListener(new SettingItemBar.OnItemClickListener() {
@Override
public void OnClick() {
Toast.makeText(MainActivity.this,"888888",Toast.LENGTH_LONG).show();
}
},0);
mSettingItemBar.setOnItemClickListener(new SettingItemBar.OnItemClickListener() {
@Override
public void OnClick() {
Toast.makeText(MainActivity.this,"77777",Toast.LENGTH_LONG).show();
}
},2);
}
}
(三)上传GitHub
参考郭霖大佬的 《第一行代码》 第二版 14.2 Git 时间——将代码托管 GitHub 上
(四)生成release版本
- 点击release
- 点击Create a new release
- 填写Tag Version,点击发布
- 发布成功,保存这个页面的网址,即带有 /releases/tag/1.0.0 的路径
(五)添加到 JitPack
- 打开网页JitPack
- 在输入框黏贴(四)中保存的路径,点击 Look up,然后点击下面的 Get it 便得到自己的依赖库的使用方法。
(六)依赖使用测试
- 新建 Android 工程
- 依据(五)中得到的方法添加依赖路径
- 在 activity_main.xml 中使用自定义的布局
<com.hzf.nicholas.settingitembarlibrary.SettingItemBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
hzf:title_text="轮子"
hzf:info_text="Good">
</com.hzf.nicholas.settingitembarlibrary.SettingItemBar>
<com.hzf.nicholas.settingitembarlibrary.SettingItemBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
hzf:icon_iv="@drawable/staff"
hzf:title_text="员工号"
hzf:info_text="123456789">
</com.hzf.nicholas.settingitembarlibrary.SettingItemBar>
- 在 MainActivity.java 中控制