图片合成文字
关键: 文字的居中: 测量文字区域的宽度
还要注意图片放置的位置: 那个drawable下,或者是raw或assert下.不同地方,scale参数不同,最终生成的图片大小也不同.
Rect bounds0 = new Rect();
textPaint.getTextBounds(compoundBean.name, 0, compoundBean.name.length(), bounds0);
int x = compoundBean.nameEndX - bounds0.width()-3;
compoundBean.nameStartX = x;
canvas.drawText(compoundBean.name, x, compoundBean.nameEndY-5, textPaint);
全部代码:
private void compoundIN(PicCompoundBean compoundBean) {
XLogUtil.e(compoundBean.toString());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap photo = BitmapFactory.decodeResource(getResources(),compoundBean.rawId,options);
int width = photo.getWidth(), hight = photo.getHeight();
System.out.println("宽"+width+"高"+hight);
Bitmap icon = Bitmap.createBitmap(width, hight, Bitmap.Config.ARGB_8888); //建立一个空的BItMap
Canvas canvas = new Canvas(icon);//初始化画布绘制的图像到icon上
Paint photoPaint = new Paint(); //建立画笔
photoPaint.setDither(true); //获取跟清晰的图像采样
photoPaint.setFilterBitmap(true);//过滤一些
Rect src = new Rect(0, 0, photo.getWidth(), photo.getHeight());//创建一个指定的新矩形的坐标
Rect dst = new Rect(0, 0, width, hight);//创建一个指定的新矩形的坐标
canvas.drawBitmap(photo, src, dst, photoPaint);//将photo 缩放或则扩大到 dst使用的填充区photoPaint
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);//设置画笔
textPaint.setTextSize(PicCompoundBean.nameFontSize);//字体大小
//textPaint.setTypeface(Typeface.DEFAULT_BOLD);//采用默认的宽度
textPaint.setColor(Color.parseColor("#ea2420"));//采用的颜色
Rect bounds0 = new Rect();
textPaint.getTextBounds(compoundBean.name, 0, compoundBean.name.length(), bounds0);
int x = compoundBean.nameEndX - bounds0.width()-3;
compoundBean.nameStartX = x;
canvas.drawText(compoundBean.name, x, compoundBean.nameEndY-5, textPaint);//绘制上去字,开始未知x,y采用那只笔绘制
/* canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();*/
Paint textPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);//设置画笔
textPaint2.setTextSize(PicCompoundBean.codeFontSize);//字体大小
textPaint2.setTypeface(Typeface.DEFAULT_BOLD);//采用默认的宽度
//textPaint2.setColor(Color.parseColor("#e72fb8"));//采用的颜色
Rect bounds = new Rect();
//textPaint2.setTextAlign(Paint.Align.CENTER);
textPaint2.getTextBounds(compoundBean.code, 0, compoundBean.code.length(), bounds);
int x2 = (width - bounds.width())/2;
compoundBean.codeStartX = x2;
textPaint2.setShader(new LinearGradient(bounds.left, bounds.top, bounds.right, bounds.bottom, Color.parseColor("#f06776"),Color.parseColor("#e72fb8"), Shader.TileMode.REPEAT));
//textPaint.setShadowLayer(3f, 1, 1,this.getResources().getColor(android.R.color.background_dark));//影音的设置
canvas.drawText(compoundBean.code, x2, compoundBean.codeStartY-14, textPaint2);//绘制上去字,开始未知x,y采用那只笔绘制
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
mIvContent.setImageBitmap(icon);
isImageSet = true;
bitmapForSave = icon;
photo.recycle();
XLogUtil.e("compoundIN---");
//saveMyBitmap(icon);
}
superAdpter在multiType下的bug:
https://github.com/hss01248/SuperAdapter
item增减时,holder = (SuperLvHolder) convertView.getTag(); 所获取的holder并非对应type的holder:
修复:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SuperLvHolder holder = null;
if (convertView == null){
holder = generateNewHolder(context,getItemViewType(position));
convertView = holder.rootView;
convertView.setTag(holder);
}else {
holder = (SuperLvHolder) convertView.getTag();
//修复multitype下的bug:
if(!(holder.type == getItemViewType(position))){
holder = generateNewHolder(context,getItemViewType(position));
convertView = holder.rootView;
convertView.setTag(holder);
}
}
holder.assingDatasAndEvents(context,datas.get(position),position,position == getCount() -1,isListViewFling,datas,this);
return convertView;
}
分享到facebook的messanger:
https://developers.facebook.com/docs/sharing/android
官方文档对messanger只有从web端打开app的url,没有Android端分享的示例,后来从Stack Overflow上找到:
其实与分享到facebook基本一样,只不过一个是用MessageDialog,一个是用ShareDialog.
if (!MessageDialog.canShow(ShareLinkContent.class)) {
callBack.onFail(new Throwable("MessageDialog.canShow(ShareLinkContent.class) is false"));
return;
}
ShareLinkContent.Builder shareLinkContentBuilder = new ShareLinkContent.Builder()
.setContentTitle(shareInfo.getShareContentTitle())
.setContentDescription(shareInfo.getShareContentDescription())
.setContentUrl(Uri.parse(shareInfo.getShareContentUrl()));
shareLinkContentBuilder.setImageUrl(Uri.parse(shareInfo.getShareImageUrl()));
MessageDialog messageDialog = new MessageDialog(activity);
messageDialog.registerCallback(callbackManager, new FacebookCallback() {
@Override
public void onSuccess(Sharer.Result result) {
callBack.onSuccess();
}
@Override
public void onCancel() {
callBack.onCancel();
}
@Override
public void onError(FacebookException error) {
callBack.onFail(error);
}
});
messageDialog.show(shareLinkContentBuilder.build());
cookie同步
项目中用到asyhttpclient,retrofit,以及webview,需要做cookie同步.
吐槽:其实项目中cookie只在登录时返回,用于后续鉴权,且后续的请求服务器不再写cookie. 鉴权模式的选择很业余,不伦不类.
同步方式1: 利用文件实现同步:
序列化到本地特定文件中,各client都从这个文件中读写cookie.同步方式2:某一client负责文件读写,其他从这个client的内存中读取:
由于asyhttpclient和retrofit中Cookie类不一样,所以需要转换:
private org.apache.http.cookie.Cookie transCookie(Cookie item) {
BasicClientCookie2 cookie = new BasicClientCookie2(item.name(),item.value());
cookie.setPath(item.path());
cookie.setDomain(item.domain());
return cookie;
}
private Cookie transCookie2(org.apache.http.cookie.Cookie item) {
Cookie cookie = new Cookie.Builder()
.domain(item.getDomain())
//.expiresAt(item.getExpiryDate().getTime())
.name(item.getName())
.path(item.getPath())
.value(item.getValue())
.build();
return cookie;
}
okhttpclient读写时拿到AsyHttpclient里的cookie:
//读cookie
@Override
public List loadForRequest(HttpUrl url) {
try {
List cookies = cookieStore.getCookies();
if(cookies ==null){
cookies = new ArrayList<>();
}
XLogUtil.obj(cookies);
List cookiesFromAsyHttp = HttpManager.getInstance().getAllCookie();
//addCookieFromAsyHttp(cookies,cookiesFromAsyHttp);
XLogUtil.obj(cookiesFromAsyHttp);
XLogUtil.obj(cookies);
return cookies ;
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
//写cookie
@Override
public void saveFromResponse(HttpUrl url, List cookies) {
try {
if (cookies != null && cookies.size() > 0) {
for (Cookie item : cookies) {
cookieStore.addCookie(item);
org.apache.http.cookie.Cookie cookie = transCookie(item);
//HttpManager.getInstance().getCookieStore().addCookie(cookie);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
webview同步来自AsyHttpclient里的cookie:
核心:
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(url, cookie);
private void syncWebViewCookie() {
List cookies = HttpManager.getInstance().getAllCookie();
Context context = MyApplication.getInstance().getApplicationContext();
Html5CookiesManger.syncCookie(context, mUrl, cookies);
}
//Html5CookiesManger
/**
* 将cookie同步到WebView
*
* @param url WebView要加载的url
* @param cookie 要同步的cookie
* @return true 同步cookie成功,false同步cookie失败
*/
private static boolean syncCookie(Context context, String url, String cookie) {
LoggerUtils.d(TAG, "context" + context);
LoggerUtils.d(TAG, "url" + url);
LoggerUtils.d(TAG, "cookie" + cookie);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(context);
}
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(url, cookie);//如果没有特殊需求,这里只需要将session id以"key=value"形式作为cookie即可
XLogUtil.e("h5 cookie2:"+cookie);
String newCookie = cookieManager.getCookie(url);
return !TextUtils.isEmpty(newCookie);
}
public static boolean syncCookie(Context context, String url, List cookies) {
String host = "";
try {
host = new URL(url).getHost().toLowerCase();// 此处获取值转换为小写
} catch (MalformedURLException e) {
e.printStackTrace();
}
LoggerUtils.d(TAG, "size = " + cookies.size());
String newCookie = "";
for (Cookie cookie : cookies) {
newCookie = cookie.getName() + "=" + cookie.getValue()
+ ";Domain=" + cookie.getDomain()
+ ";Path=" + cookie.getPath();
XLogUtil.e("h5 cookie:"+newCookie);
syncCookie(context, host, newCookie);
LoggerUtils.d(TAG, "cookie" + cookie);
LoggerUtils.d(TAG, "host" + host);
LoggerUtils.d(TAG, "getDomain" + cookie.getDomain());
}
return syncCookie(context, host, newCookie);
}