Droidlover

Droidlovers


  • 首页

  • 归档

  • 标签
Droidlover

XTrace

发表于 2016-11-19 |

XTrace

XTrace是AOP在Android的简单实践,踩了一系列坑。希望能帮助您
将AOP运用到Android。欢迎star、fork,期待提出您的宝贵意见。

以下是我的踩坑笔记

AOP概述

做过J2EE开发的同学对AOP一定非常熟悉,在J2EE中,面向切面编程的实现一般有AspectJ、Spring Aop等,抱歉,我只用过这两个。AOP的主要名词 有:Aspect、Pointcut、Advise等。在这里,我选用AspectJ做Android平台的AOP。

Gradle插件

AspectJ是在编译阶段对字节码进行操作,因此需要它独立的编译器ajc。在Android Studio中,可以通过Gradle脚本启用ajc编译器。为了方便开发AOP,我搞了个小插件(很简单的),在需要引入AOP的library或Application中引入就好。

1
2
3
4
5
6
7
8
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'cn.droidlover:AspectJAs:1.0.2'
}
}

在相应的模块中使用插件:

1
apply plugin: 'cn.droidlover.aspectjas'

开发Gradle插件遇到的坑
 需要在java目录下建立resources/META-INF/gradle-plugins目录  需要在radle-plugins目录下建立plugin_name.properties文件。如上面的插件名称为cn.droidlover.aspectjas,则该文件名应为:cn.droidlover.aspectjas.properties
* 文件内容为:

1
implementation-class=插件入口path

如上述插件则为:
1
implementation-class=cn.droidlover.aspectjas.AspectJAs
插件入口即 class implements Plugin<Project>的类,每个插件只有一个入口。
  • 可以将自己写的插件上传到本地maven仓库
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    apply plugin: 'groovy'
    apply plugin: "maven"
    dependencies {
    compile gradleApi()
    compile localGroovy()
    compile 'com.android.tools.build:gradle:2.1.0'
    }
    repositories {
    jcenter()
    }
    // 上传到本地代码库
    uploadArchives{
    repositories{
    mavenDeployer{
    repository(url:uri('../repo'))
    pom.groupId = 'cn.droidlover' // 组名
    pom.artifactId = 'AspectJAs' // 插件名
    pom.version = '1.0.2' // 版本号
    }
    }
    }

使用的时候只需要加上maven地址就好:

1
2
3
maven{
url uri('/repo')
}

XTrace说明

XTrace的目标是具有@Trace注解的方法,其主要功能是:将执行方法标识、执行方法名称、执行参数传值、执行时间、返回值等进行Log日志输出。


xtrace_1 image

运行截图


xtrace_2 image

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Trace("聊天")
public void onChat(View view) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Trace("求和")
private int sum(int a, int b) {
return a + b;
}

您可以根据这个进行扩展,比如进行用户行为的统计等。

Droidlover

TagEditText

发表于 2016-11-19 |

TagEditText,类似微博标签的文本控件

TagEditText实现了显示类似微博中的活动标签, 其特点是将一段文字中用’#’包裹的部分以特殊的颜色显示,并能进行点击交互。


tagedittext image

主要功能

  • 自定义包裹符号,如# … # 或者 … ,或者 # … * ,具体什么符号可以自定义,默认是 # … #
  • 自定义匹配的标签字体颜色
  • 自定义标签点击事件

使用

  • Gradle : compile ‘cn.droidlover:TagEditText:1.0.0’’
  • Github : TagEditText

说明

库中主要包括两个控件:

  • TagEditText :主要用于用户评论的编辑,用户可输入类似#…#的内容。
  • TagTextView :主要用于显示内容。

主要用法

TagTextView

1
2
3
4
5
6
<cn.droidlover.tagedittext.TagTextView
android:id="@+id/tagTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:textSize="14sp" />

在java中

1
2
3
4
5
6
7
8
9
10
11
12
tagTextView
.tagColor(Color.RED) //设置标签颜色
.tag("#", "#"); //设置前后匹配符
tagTextView.setCallback(new TagSpan.Callback<String>() { //设置标签点击事件
@Override
public void onClick(String data) {
toast(data);
}
})
tagTextView.text(str); //设置内容

TagEditText

1
2
3
4
5
6
7
8
9
<cn.droidlover.tagedittext.TagEditText
android:id="@+id/tagEditText"
android:layout_width="match_parent"
android:hint="TagEditText"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="@android:color/transparent"
android:padding="16dp"
android:textSize="14sp" />

在java中

1
2
3
4
5
6
tagEditText
.tag("#", "#") //设置前后匹配符
.tagColor(Color.BLUE); //设置标签颜色
tagEditText.appendText(""); //追加文本
tagEditText.getTagList(); //获取标签集合
tagEditText.removeText(""); //删除指定
Droidlover

XRichText

发表于 2016-11-19 |

XRichText


XRichText是一个可以显示Html富文本的TextView。可以用于显示新闻、商品详情等场景。欢迎star、fork,提出意见。


xrichtext image

使用

  • Gradle : compile ‘cn.droidlover:XRichText:1.0.0’
  • Github : XRichText

特别说明:

可以直接调用text方法显示html,其他的接口只是应对特殊场景的。

主要特性

  • 自定义超链接link的点击
  • 自定义图片img的点击
  • 支持链式调用
  • 图片支持三种对齐方式(左对齐、居中、右对齐)
  • 支持在图片加载前对每张图片的url、width、height、对齐方式精细调整
  • 内置图片下载器
  • 可自定义图片下载器,如使用universal image loader、Picasso、Glide等

实现原理

  • spanned
  • 线程池
  • 自定义ImageGetter

示例

1
2
3
4
5
<cn.droidlover.xrichtext.XRichText
android:id="@+id/richText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp" />

在Java中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
richText
.callback(new XRichText.BaseClickCallback() {
@Override
public boolean onLinkClick(String url) {
showMsg(url);
return true;
}
@Override
public void onImageClick(List<String> urlList, int position) {
super.onImageClick(urlList, position);
showMsg("图片:" + position);
}
@Override
public void onFix(XRichText.ImageHolder holder) {
super.onFix(holder);
if (holder.getPosition() % 3 == 0) {
holder.setStyle(XRichText.Style.LEFT);
} else if (holder.getPosition() % 3 == 1) {
holder.setStyle(XRichText.Style.CENTER);
} else {
holder.setStyle(XRichText.Style.RIGHT);
}
//设置宽高
holder.setWidth(550);
holder.setHeight(400);
}
})
.imageDownloader(new ImageLoader() {
@Override
public Bitmap getBitmap(String url) throws IOException {
return UILKit.getLoader().loadImageSync(url);
}
})
.text(TEXT);

api说明

  • onLinkClick(String url) 当点击超链接时触发,url为点击的url
  • onImageClick(List urlList, int position) 当点击图片时触发,urlList为图片的url集合,position为被点击的位置,从0开始
  • onFix(XRichText.ImageHolder holder) 当图片加载前回调此方法,通过holder可以调整图片的src、width、height、style(对齐方式)
  • 设置html内容时,务必调用text方法
  • imageDownloader(ImageLoader loader)可以自定义图片加载器,库中已有默认实现。可以根据项目情况定义加载器,如三方库UIL、Picasso等,只需实现ImageLoader接口就行。getBitmap方法已经在线程池中,所以自定义loader时不必考虑线程问题.
  • ClickCallback接口有默认实现类BaseClickCallback,可以直接使用此类重写需要的方法。
Droidlover

XAnimLayout

发表于 2016-11-19 |

XAnimLayout 让引导页动画easy

XAnimLayout封装了常见的引导页动画,仅仅需要在xml中设置相关属性,即可实现translate、rotate、alpha、scale、colorGradient等动画。


xanimlayout image

主要功能

  • 实现常用的动画效果
  • 自定义属性
  • 扩展性强

使用

  • Gradle : compile ‘cn.droidlover:XAnimLayout:1.0.0’’
  • Github : XAnimLayout

说明

库中包括两部分:

  • AnimScrollView :继承ScrollView,用于滑动和滑动状态的监听。
  • AnimLinearLayout :AnimScrollView的直接子view

主要用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<cn.droidlover.xanimlayout.AnimScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<cn.droidlover.xanimlayout.AnimLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:al_firstFillViewPort="true">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#BDF0B9"
android:gravity="center"
android:text="XAnimLayout"
android:textColor="#fff"
android:textSize="22sp"
app:av_alpha="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#FFE2C8"
android:gravity="center"
android:text="RxJava"
android:textColor="#fff"
android:textSize="22sp"
app:av_translateGravity="right" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Dagger"
android:textSize="22sp"
app:av_endColorBg="#140405"
app:av_startColorBg="#A15772" />
<TextView
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#BAE4D0"
android:gravity="center"
android:text="Android"
android:textSize="28sp"
app:av_alpha="true" />
</cn.droidlover.xanimlayout.AnimLinearLayout>
</cn.droidlover.xanimlayout.AnimScrollView>

不需要任何java代码,即可实现开场动画。

使用解析

AnimLinearLayout

AnimLinearLayout包含一个自定义属性:al_firstFillViewPort 。若true,则其第一个子view的高度就会占满全屏。若false,则其高度不被调整。此属性默认为true。

支持的属性

1
2
3
4
5
6
7
8
9
10
11
12
<attr name="av_rotate" format="boolean" />
<attr name="av_alpha" format="boolean" />
<attr name="av_scaleX" format="boolean" />
<attr name="av_scaleY" format="boolean" />
<attr name="av_startColorBg" format="color" />
<attr name="av_endColorBg" format="color" />
<attr name="av_translateGravity">
<flag name="left" value="0x01" />
<flag name="top" value="0x02" />
<flag name="right" value="0x04" />
<flag name="bottom" value="0x08" />
</attr>

属性说明:

  • av_rotate:boolean 表示是否可旋转
    • true 有旋转动画
    • false 没有旋转动画
  • av_alpha:Boolean 表示是否有alpha动画
    • true 伴随alpha动画
    • false 没alpha动画
  • av_scaleX 表示x方向的scale动画
  • av_scaleY 表示y方向的scale动画
  • av_startColorBg与av_endColorBg配对使用,作用于该view的background,分别表示开始颜色、结束颜色
  • av_translateGravity 表示translate的开始方向,有left、top、right、bottom等值,默认为-1,需要说明的是,此属性与传统的gravity用法类似,可组合使用
1
app:av_translateGravity="right"

或者使用两个值

1
app:av_translateGravity="right|bottom"

Droidlover

XSharedPref

发表于 2016-11-19 |

XSharedPref,适用于多进程的SharedPreferences

SharedPreferences底层是操作xml文件。在多进程中,每个进程都有一份SharedPreferences,因此SharedPreferences不能直接在多进程通信。为了解决此问题,将SharedPreferences的操作放在一个单独的进程中,其他进程使用ContentProvider对它进行操作,XSharedPref由此产生。

两个部分

  • SharedPrefProvider 继承了ContentProvider,实现对SharedPreferences的基本操作。
  • XSharedPref SharedPreferences使用工具类,其Api类似SharedPreferences。主要实现了:
    • getString
    • getInt
    • getLong
    • getFloat
    • getBoolean
    • putString
    • putInt
    • putLong
    • putFloat
    • putBoolean
    • remove
    • clear
    • contains
      等基本操作,您可以根据自己的实际情况进行扩展。

使用用法

  1. gradle配置
    compile ‘cn.droidlover:xsharedpref:1.0.0’

  2. AndroidManifest.xml配置ContentProvider

    1
    2
    3
    4
    <provider
    android:name=".SharedPrefProvider"
    android:authorities="cn.droidlover.xsharedpref.sp"
    android:process=":xSharedPref" />

    process配置进程名称

  3. 使用XSharedPref提供的api

    1
    2
    XSharedPref.putString(this, "github_name", "https://github.com/limedroid");
    String gitName = XSharedPref.getString(this, "github_name", null);

    其他的api操作也如上所述.

  

Droidlover

ARecyclerView

发表于 2016-11-19 |

ARecyclerView

对RecyclerView的封装,功能强大、使用简单、扩展性强。该库主要分成三部分:RecyclerAdapter、XRecyclerView、XRecyclerContentLayout

该库在商业项目中历经一年多时间打磨,欢迎star、fork,后期会有更多分享,期待您的建议和关注。


arecyclerview image

使用

  • Gradle : compile ‘cn.droidlover:XRecyclerView:1.0.0’
  • Github : ARecyclerView

RecyclerAdapter

RecyclerAdapter简化了Adapter的开发,封装了一些常用的逻辑,包括数据集合操作、接口监听RecyclerItemCallback可以满足99%的需求。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
public class TestRecAdapter extends RecyclerAdapter<TestRecAdapter.Item, TestRecAdapter.ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
}
}

XRecyclerView

XRecyclerView是对RecyclerView的封装,其主要特性包括:

  • 一行代码添加、删除、修改Header或者Footer
  • 一行代码添加默认的上拉加载效果
  • 一行代码切换自定义上拉加载效果
  • 一行代码轻松添加LayoutManager
  • 一行代码添加divider
  • Adapter规范及封装RecyclerAdapter

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
recyclerView.verticalLayoutManager(this) //设置layoutManager
.setAdapter(adapter); //设置Adapter
recyclerView.horizontalDivider(R.color.x_red, R.dimen.divider_height); //设置divider
recyclerView.setOnRefreshAndLoadMoreListener(new XRecyclerView.OnRefreshAndLoadMoreListener() { //设置刷新和上拉加载监听
@Override
public void onRefresh() {
loadData(1);
}
@Override
public void onLoadMore(int page) {
loadData(page);
}
});
recyclerView.useDefLoadMoreView(); //使用默认的上拉刷新样式
recyclerView.addHeaderView(headView); //添加header
recyclerView.addFooterView(footview); //添加footer
recyclerView.removeHeaderView(headview); //删除header
recyclerView.removeFooterView(footview); //删除footer

XRecyclerContentLayout

XRecyclerContentLayout继承了QTContentLayout,可自定义Loading、Error、Empty、Content四种显示状态,满足了绝大部分需求.

使用示例

1
2
3
4
5
6
7
<cn.droidlover.xrecyclerview.XRecyclerContentLayout
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:recyclerBackgroundColor="#f5f5f5"
app:recyclerScrollbarNone="true"
app:recyclerScrollbarStyle="outsideOverlay" />
1
2
3
4
5
6
7
8
contentLayout.loadingView(new LoadingView(this));
.errorView(new ErrorView(this));
.emptyView(new EmptyView(this));
contentLayout.showLoading();
contentLayout.showError();
contentLayout.showEmpty();
contentLayout.showContent();

自定义LoadMoreView的实现

自定义LoaderMoreView只需实现LoadMoreUIHandler接口,然后调用xrecyclerView的loadMoreFooterView(loadMoreView)方法即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public void onLoading() {
setVisibility(VISIBLE);
tvMsg.setText("加载中");
progressBar.setVisibility(VISIBLE);
}
@Override
public void onLoadFinish(boolean hasMore) {
if (hasMore) {
setVisibility(GONE);
} else {
setVisibility(VISIBLE);
tvMsg.setText("没有更多数据");
progressBar.setVisibility(GONE);
}
}

设置loadMoreView

1
recyclerView.loadMoreFooterView(loadMoreView);

自定义实现XRecyclerContentLayout

在XRecyclerContentLayout中内置了SwipeRefreshLayout下拉刷新样式,您也可以自定义实现XRecyclerContentLayout,只需实现XRecyclerView.StateCallback接口即可.

1
2
3
4
5
6
7
8
9
public interface StateCallback {
void notifyEmpty(); //数据为空
void notifyContent(); //显示contentview
void refreshState(boolean isRefresh); //更新刷新状态
void refreshEnabled(boolean isEnabled); //刷新是否可用
}

详情demo可见app module。

WangLei

WangLei

A Android Coder

6 日志
9 标签
© 2016 WangLei
由 Hexo 强力驱动
主题 - NexT.Pisces