Android中能夠簡(jiǎn)化開(kāi)發(fā)流程的一些框架
本文介紹的是一些博主在開(kāi)發(fā)過(guò)程中經(jīng)常用到的Android開(kāi)源框架掏湾,所謂開(kāi)源框架我的理解就是別人封裝好的代碼铣减,可以直接拿過(guò)來(lái)使用,并且源碼也全部公開(kāi)的代碼庫(kù)凶掰。
我對(duì)于開(kāi)源框架的使用的態(tài)度是闻坚,如果完全符合我們項(xiàng)目的需求,或者可定制化的程度非常高的話逝她,那么便可以拿過(guò)來(lái)直接用,因?yàn)殚_(kāi)源框架的源碼都在那里睬捶,如果遇到和項(xiàng)目預(yù)期不一樣的地方我們也可以把源碼拿過(guò)來(lái)自己改一下黔宛,然后重新打個(gè)包嘛。
但是擒贸,不是很建議剛開(kāi)始學(xué)習(xí)安卓的小伙伴們臀晃,只會(huì)用第三方框架,但是不理解框架內(nèi)部的實(shí)現(xiàn)介劫,在用第三方框架的過(guò)程中徽惋,我們是可以自己先封裝一下簡(jiǎn)單的框架的,然后再了解一下別人框架內(nèi)部實(shí)現(xiàn)的邏輯什么樣的座韵,知其所以然嘛险绘。
同時(shí)也非常感謝這些開(kāi)源框架的作者們,他們的開(kāi)源精神誉碴,真的是非常的偉大啊宦棺。
網(wǎng)絡(luò)框架
Json解析框架
圖片加載框架
Log類(lèi)的庫(kù)
RecyclerView
Adapter
數(shù)據(jù)庫(kù)
注解庫(kù)
事件總線
圖片剪裁
性能檢測(cè)
后臺(tái)任務(wù)隊(duì)列
UI
感覺(jué)這么給大家介紹完了,可能大家會(huì)感覺(jué)到很抽象黔帕,所以打算動(dòng)手?jǐn)]一個(gè)小的項(xiàng)目代咸,讓大家具體感受一下大神們封裝的庫(kù)
項(xiàng)目中用到的庫(kù):
- nohttp
- butterknife
- glide
- logger
- BaseRecyclerViewAdapterHelper
- eventbus
- glide-transformations
- leakcanary
- Android-Bootstrap
- TastyToast
- material-dialogs
項(xiàng)目截圖:

nohttp:
//同步請(qǐng)求,結(jié)果直接存儲(chǔ)在了response
Request<String> request = NoHttp.createStringRequest("自己的url", RequestMethod.POST);
Response<String> response = NoHttp.startRequestSync(request);
String result = response.get();
//可以直接將結(jié)果取出成黄,并且內(nèi)置了Gson呐芥,fastJson逻杖,可以直接將結(jié)果轉(zhuǎn)換成對(duì)應(yīng)的model
//異步請(qǐng)求,可以構(gòu)建請(qǐng)求隊(duì)列思瘟,默認(rèn)同時(shí)三個(gè)請(qǐng)求一起荸百,參數(shù)可調(diào)
RequestQueue requestQueue = NoHttp.newRequestQueue();
OnResponseListener<String> listener = new OnResponseListener<String>() {
@Override public void onStart(int what) {
}
@Override public void onSucceed(int what, Response response) {
}
@Override public void onFailed(int what, Response response) {
}
@Override public void onFinish(int what) {
}
};
//請(qǐng)求String
Request<String> request2 = NoHttp.createStringRequest("自己的url", RequestMethod.GET);
requestQueue.add(0, request2, listener);
//可以自定義請(qǐng)求類(lèi)型
/*
// JsonObject
Request<JSONObject> objRequest = NoHttp.createJsonObjectRequest("自己的url", RequestMethod.POST);
requestQueue.add(0, objRequest, listener);
// JsonArray
Request<JSONArray> arrayRequest = NoHttp.createJsonArrayRequest("自己的url", RequestMethod.PUT);
requestQueue.add(0, arrayRequest, listener);
Request<JSONObject> request = new FastJsonRequest(url, RequestMethod.POST);
requestQueue.add(0, request, listener);
// 內(nèi)部使用Gson、FastJson解析成JavaBean
Request<UserInfo> request = new JavaBeanRequest(url, RequestMethod.GET);
requestQueue.add(0, request, listener);
Request<JSONObject> request = new JavaBeanRequest(url, RequestMethod.POST);
.add("name", "yoldada") // String類(lèi)型
.add("age", 18) // int類(lèi)型
.add("sex", '0') // char類(lèi)型
.add("time", 16346468473154) // long類(lèi)型
// 添加Bitmap
.add("head", new BitmapBinary(bitmap))
// 添加File
.add("head", new FileBinary(file))
// 添加ByteArray
.add("head", new ByteArrayBinary(byte[]))
// 添加InputStream
.add("head", new InputStreamBinary(inputStream));
*/
//nohttp同時(shí)有非常完備的緩存的策略潮太,同時(shí)對(duì)文件上傳管搪,請(qǐng)求包體都有非常好的兼容,并且全都是中文文檔~
butterknife:
@BindView(R.id.title) TextView title;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
title.setText("一些第三方庫(kù)的測(cè)試的demo");
}
@OnClick(R.id.nohttp) public void onNohttpClicked() {
startActivity(new Intent(MainActivity.this, NoHttpActivity.class));
}
@OnClick(R.id.glide) public void onGlideClicked() {
startActivity(new Intent(MainActivity.this,GlideActivity.class));
}
@OnClick(R.id.baseRecyclerview_adapter_helper) public void onBaseRecyclerviewAdapterHelperClicked() {
startActivity(new Intent(MainActivity.this,BaseRecyclerViewAdapterActivity.class));
}
@OnClick(R.id.event_bus) public void onEventBusClicked() {
startActivity(new Intent(MainActivity.this,EventBusActivity.class));
}
@OnClick(R.id.glide_transformations) public void onGlideTransformationsClicked() {
startActivity(new Intent(MainActivity.this,GlideTransFormationActivity.class));
}
@OnClick(R.id.tasty_toast) public void onTastyToastClicked() {
startActivity(new Intent(MainActivity.this,TastyToastActivity.class));
}
@OnClick(R.id.material_dialogs) public void onMaterialDialogsClicked() {
startActivity(new Intent(MainActivity.this,MaterialDialogActivity.class));
}
@OnClick(R.id.logger) public void onLoggerClicked() {
startActivity(new Intent(MainActivity.this,LoggerActivity.class));
}
glide:
Glide.with(this).load("http://goo.gl/gEgYUd").into(img1);
Glide.with(this)
.load("http://goo.gl/gEgYUd")
.fitCenter()
.centerCrop()
.into(img2);
Glide.with(this)
.load("")
.fitCenter()
.centerCrop()
.error(R.mipmap.ic_launcher)
.into(img3);
Glide.with(this)
.load("http://goo.gl/gEgYUd")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(img4);
Glide.with(this)
.load("http://goo.gl/gEgYUd")
.crossFade()
.into(img5);
Glide.with(this)
.load("http://goo.gl/gEgYUd")
.into(new SimpleTarget<GlideDrawable>() {
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
img6.setImageDrawable(resource);
}
});

logger:
Logger.d("hello");
Logger.d("hello %s %d", "world", 5); // String.format
Logger.d("hello");
Logger.e("hello");
Logger.w("hello");
Logger.v("hello");
Logger.wtf("hello");
// Logger.json(JSON_CONTENT); //打印json
// Logger.xml(XML_CONTENT);
// Logger.log(DEBUG, "tag", "message", throwable);
// Logger.d("hello %s", "world");
//
// Logger.d(list); //打印list
// Logger.d(map);
// Logger.d(set);
// Logger.d(new String[]);
//
// Logger
// .init(YOUR_TAG) // default PRETTYLOGGER or use just init()
// .methodCount(3) // default 2
// .hideThreadInfo() // default shown
// .logLevel(LogLevel.NONE) // default LogLevel.FULL
// .methodOffset(2) // default 0
// .logAdapter(new AndroidLogAdapter()); //default AndroidLogAdapter
//
//
//
Logger.log(5000, "tag", "內(nèi)容", null);//延時(shí)打log

BaseRecyclerViewAdapterHelper:
MultipleItem item1 = new MultipleItem(1, "aaa");
MultipleItem item2 = new MultipleItem(1, "bbb");
MultipleItem item3 = new MultipleItem(1, "ccc");
MultipleItem item4 = new MultipleItem(1, "ddd");
MultipleItem item5 = new MultipleItem(2, "");
MultipleItem item6 = new MultipleItem(2, "");
List<MultipleItem> list = new ArrayList<MultipleItem>();
list.add(item1);
list.add(item2);
list.add(item5);
list.add(item3);
list.add(item4);
list.add(item6);
MultipleItemQuickAdapter adapter = new MultipleItemQuickAdapter(list);
adapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() {
@Override public int getSpanSize(GridLayoutManager gridLayoutManager, int position) {
if (position == 2 || position == 5) {
return 4;
} else {
return 2;
}
}
});
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
recyclerView.setAdapter(adapter);
//輕松實(shí)現(xiàn)多種布局铡买,點(diǎn)擊事件等
//添加動(dòng)畫(huà)等
adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {//item點(diǎn)擊事件
@Override public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(BaseRecyclerViewAdapterActivity.this, "點(diǎn)擊了" + position, Toast.LENGTH_SHORT).show();
}
});
//adapter.addHeaderView();添加headerview
//可以?xún)?yōu)化Adapter代碼
//添加Item事件
//添加列表加載動(dòng)畫(huà)
//添加頭部更鲁、尾部
//自動(dòng)加載
//添加分組
//自定義不同的item類(lèi)型
//設(shè)置空布局
//添加拖拽、滑動(dòng)刪除
//分組的伸縮欄
//自定義ViewHolder
}
public class MultipleItem implements MultiItemEntity {
public static final int TEXT = 1;
public static final int IMG = 2;
public String text;
private int itemType;
public MultipleItem(int itemType, String text) {
this.itemType = itemType;
this.text = text;
}
@Override
public int getItemType() {
return itemType;
}
}
public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter<MultipleItem, BaseViewHolder> {
public MultipleItemQuickAdapter(List data) {
super(data);
addItemType(MultipleItem.TEXT, R.layout.item_recycler_view);
addItemType(MultipleItem.IMG, R.layout.item_recycler_view2);
}
@Override
protected void convert(BaseViewHolder helper, MultipleItem item) {
switch (helper.getItemViewType()) {
case MultipleItem.TEXT:
helper.setText(R.id.text, item.text);
break;
case MultipleItem.IMG:
//可以在這里面設(shè)置圖片奇钞,現(xiàn)在默認(rèn)是背景圖片
break;
}
}
}

eventbus:
//當(dāng)然澡为,我們目前將,發(fā)送與接收放在了一個(gè)界面里面景埃,他們可以在不同的界面里面媒至,可以實(shí)現(xiàn)app內(nèi)部的通信
@Override protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eventbus);
ButterKnife.bind(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(EventBusActivity.this, "收到的內(nèi)容 -> " + event.event, Toast.LENGTH_SHORT).show();
}
@Override protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
@OnClick(R.id.send) public void onViewClicked() {
EventBus.getDefault().post(new MessageEvent("今天好開(kāi)心"));
}
public class MessageEvent{
String event;
public MessageEvent(String event){
this.event = event;
}
}

glide-transformations:
//可以修改顏色,加濾鏡谷徙,剪裁拒啰,gpu加速等
Glide.with(this).load("https://ws1.sinaimg.cn/large/006tNbRwly1ffs6l68mx3j30ge0gen08.jpg")
.bitmapTransform(new BlurTransformation(this, 30), new CropCircleTransformation(this))
.into((ImageView) findViewById(R.id.img1));
Glide.with(this).load("https://ws1.sinaimg.cn/large/006tNbRwly1ffs6l68mx3j30ge0gen08.jpg")
.bitmapTransform(new CropCircleTransformation(this))
.into((ImageView) findViewById(R.id.img2));
Glide.with(this).load("https://ws1.sinaimg.cn/large/006tNbRwly1ffs6l68mx3j30ge0gen08.jpg")
.bitmapTransform(new CropSquareTransformation(this))
.into((ImageView) findViewById(R.id.img3));
Glide.with(this).load("https://ws1.sinaimg.cn/large/006tNbRwly1ffs6l68mx3j30ge0gen08.jpg")
.bitmapTransform(new ColorFilterTransformation(this, 0x80dfdfdf))
.into((ImageView) findViewById(R.id.img4));

leakcanary:
/*
* LeakCanary用來(lái)專(zhuān)注分析系統(tǒng)的進(jìn)程
*/
if (LeakCanary.isInAnalyzerProcess(this)) {
return;
}

Android-Bootstrap:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:orientation="vertical"
tools:context="com.dotengine.linsir.basedevelop.MainActivity">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="常用庫(kù)的demo"
android:textSize="20sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#dfdfdf"/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/nohttp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="nohttp"
app:bootstrapBrand="success"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="false"
android:layout_marginTop="12dp"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/glide"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="glide"
android:layout_marginTop="12dp"
app:bootstrapBrand="warning"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="false"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/baseRecyclerview_adapter_helper"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="baseRecyclerView-Adapter-Helper"
android:layout_marginTop="12dp"
app:bootstrapBrand="primary"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="false"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/event_bus"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="eventbus"
android:layout_marginTop="12dp"
app:bootstrapBrand="danger"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="false"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/glide_transformations"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="12dp"
android:text="glide-transformations"
app:bootstrapBrand="success"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="true"/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/tasty_toast"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="TastyToast"
android:layout_marginTop="12dp"
app:bootstrapBrand="warning"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="true"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/material_dialogs"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="material-dialogs"
android:layout_marginTop="12dp"
app:bootstrapBrand="primary"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="true"
/>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/logger"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="logger"
android:layout_marginTop="12dp"
app:bootstrapBrand="danger"
app:bootstrapSize="lg"
app:buttonMode="regular"
app:roundedCorners="true"
app:showOutline="true"
/>
</LinearLayout>

TastyToast:
@OnClick(R.id.button1) public void onButton1Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.WARNING);
}
@OnClick(R.id.button2) public void onButton2Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.CONFUSING);
}
@OnClick(R.id.button3) public void onButton3Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.DEFAULT);
}
@OnClick(R.id.button4) public void onButton4Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
@OnClick(R.id.button5) public void onButton5Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.INFO);
}
@OnClick(R.id.button6) public void onButton6Clicked() {
TastyToast.makeText(getApplicationContext(), "Hello World !", TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
}


material-dialogs:
@OnClick(R.id.button1) public void onButton1Clicked() {
new MaterialDialog.Builder(this)
.title("標(biāo)題")
.content("是否同意")
.positiveText("同意")
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "同意", Toast.LENGTH_SHORT).show();
}
})
.negativeText("不同意")
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "不同意", Toast.LENGTH_SHORT).show();
}
})
.show();
}
@OnClick(R.id.button2) public void onButton2Clicked() {
MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
.title("標(biāo)題")
.content("是否同意")
.positiveText("同意");
MaterialDialog dialog = builder.build();
dialog.show();
//dialog.dismiss();
}
@OnClick(R.id.button3) public void onButton3Clicked() {
new MaterialDialog.Builder(this)
.title("標(biāo)題")
.content("是否同意")
.positiveText("1111")
.negativeText("2222")
.neutralText("3333")
.show();
}
@OnClick(R.id.button4) public void onButton4Clicked() {
new MaterialDialog.Builder(this)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "1111", Toast.LENGTH_SHORT).show();
}
})
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "2222", Toast.LENGTH_SHORT).show();
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "3333", Toast.LENGTH_SHORT).show();
}
})
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "4444", Toast.LENGTH_SHORT).show();
}
});
}
@OnClick(R.id.button5) public void onButton5Clicked() {
new MaterialDialog.Builder(this)
.iconRes(R.mipmap.ic_launcher)
.limitIconToDefaultSize()
.title("test")
.positiveText("allow")
.negativeText("deny")
.onAny(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Toast.makeText(MaterialDialogActivity.this, "Prompt checked? " + dialog.isPromptCheckBoxChecked(), Toast.LENGTH_SHORT).show();
}
})
.checkBoxPromptRes(R.string.app_name, false, null)
.show();
}
@OnClick(R.id.button6) public void onButton6Clicked() {
new MaterialDialog.Builder(this)
.title("test")
.items(R.array.good)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
Toast.makeText(MaterialDialogActivity.this, "點(diǎn)擊的是 " + which, Toast.LENGTH_SHORT).show();
}
})
.show();
}
@OnClick(R.id.button7) public void onButton7Clicked() {
new MaterialDialog.Builder(this)
.title("test")
.items(R.array.good)
.itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
/**
* If you use alwaysCallSingleChoiceCallback(), which is discussed below,
* returning false here won't allow the newly selected radio button to actually be selected.
**/
return true;
}
})
.positiveText(R.string.app_name)
.show();
}


以上便是對(duì)這些庫(kù)的一個(gè)小的總結(jié),大家如果感覺(jué)這些庫(kù)不錯(cuò)的話完慧,建議上github上面看一下他們的文檔谋旦,可以學(xué)到更多的用法,并且可以看到他們的源碼屈尼。希望大家同樣可以上github給我star册着,或者follow~
項(xiàng)目源碼下載