开发笔记-Android-2017-11-15-图片合成文字-cookie同步-listview的multiType

图片合成文字

关键: 文字的居中: 测量文字区域的宽度
还要注意图片放置的位置: 那个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<Sharer.Result>() {
            @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<Cookie> loadForRequest(HttpUrl url) {
        try {
            List<Cookie> cookies = cookieStore.getCookies();
            if(cookies ==null){
                cookies = new ArrayList<>();
            }
            XLogUtil.obj(cookies);

            List<org.apache.http.cookie.Cookie> 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<Cookie> 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<Cookie> 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<Cookie> 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);
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容