Android——Label样式

转载 2015年11月20日 16:50:04

样式:
这里写图片描述

使用:

        final LabelView myLabel = new LabelView(this);
        myLabel.setText("hq");
        myLabel.setBackgroundColor(0xffE91E63);
//      参数1:目标view
//      参数2:徽章距离view顶角的距离
//      参数3:徽章的位置
        myLabel.setTargetView(findViewById(R.id.myImg), 0, LabelView.Gravity.LEFT_TOP);

        final LabelView myLabel1 = new LabelView(this);
        myLabel1.setText("");
        myLabel1.setBackgroundColor(0xffE91E63);
        myLabel1.setTargetView(findViewById(R.id.myImg1), 0, LabelView.Gravity.RIGHT_TOP);

        final LabelView myLabel2 = new LabelView(this);
        myLabel2.setText("hq");
        myLabel2.setBackgroundColor(0xffE91E63);
        myLabel2.setTargetView(findViewById(R.id.myImg2), 5, LabelView.Gravity.RIGHT_TOP);

源码:

/*
 * Copyright (C) 2011 The Android Open Source Project
 * Copyright 2014 linger1216
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lid.lib;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.concurrent.atomic.AtomicInteger;

public class LabelView extends TextView {

    private float _offsetx;
    private float _offsety;
    private float _anchorx;
    private float _anchory;
    private float _angel;
    private int _labelViewContainerID;
    private Animation _animation = new Animation() {
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            Matrix tran = t.getMatrix();
            tran.postTranslate(_offsetx, _offsety);
            tran.postRotate(_angel, _anchorx, _anchory);
        }
    };

    public enum Gravity {
        LEFT_TOP, RIGHT_TOP
    }

    public LabelView(Context context) {
        this(context, null);
    }

    public LabelView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public LabelView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        init();

        _animation.setFillBefore(true);
        _animation.setFillAfter(true);
        _animation.setFillEnabled(true);

    }


    private void init() {

        if (!(getLayoutParams() instanceof ViewGroup.LayoutParams)) {
            LayoutParams layoutParams =
                    new LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT);
            setLayoutParams(layoutParams);
        }

        // the default value
        //setPadding(dip2Px(40), dip2Px(2), dip2Px(40), dip2Px(2));
        _labelViewContainerID = -1;

        setGravity(android.view.Gravity.CENTER);
        setTextColor(Color.WHITE);
        setTypeface(Typeface.DEFAULT_BOLD);
        setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
        setBackgroundColor(Color.BLUE);
    }

    public void setTargetView(View target, int distance, Gravity gravity) {

        if (!replaceLayout(target)) {
            return;
        }

        final int d = dip2Px(distance);
        final Gravity g = gravity;
        final View v = target;

        ViewTreeObserver vto = getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                calcOffset(getMeasuredWidth(), d, g, v.getMeasuredWidth(), false);
            }
        });

    }


    public void setTargetViewInBaseAdapter(View target, int targetWidth, int distance, Gravity gravity) {
        if (!replaceLayout(target)) {
            return;
        }
        //measure(0, 0);
        //calcOffset(getMeasuredWidth(), distance, gravity, targetWidth, true);
        calcOffset(dip2Px(targetWidth), distance, gravity, targetWidth, true);
    }

    public void remove() {
        if (getParent() == null || _labelViewContainerID == -1) {
            return;
        }

        ViewGroup frameContainer = (ViewGroup) getParent();
        assert (frameContainer.getChildCount() == 2);
        View target = frameContainer.getChildAt(0);

        ViewGroup parentContainer = (ViewGroup) frameContainer.getParent();
        int groupIndex = parentContainer.indexOfChild(frameContainer);
        if (frameContainer.getParent() instanceof RelativeLayout) {
            for (int i = 0; i < parentContainer.getChildCount(); i++) {
                if (i == groupIndex) {
                    continue;
                }
                View view = parentContainer.getChildAt(i);
                RelativeLayout.LayoutParams para = (RelativeLayout.LayoutParams) view.getLayoutParams();
                for (int j = 0; j < para.getRules().length; j++) {
                    if (para.getRules()[j] == _labelViewContainerID) {
                        para.getRules()[j] = target.getId();
                    }
                }
                view.setLayoutParams(para);
            }
        }

        ViewGroup.LayoutParams frameLayoutParam = frameContainer.getLayoutParams();
        target.setLayoutParams(frameLayoutParam);
        parentContainer.removeViewAt(groupIndex);
        frameContainer.removeView(target);
        frameContainer.removeView(this);
        parentContainer.addView(target,groupIndex);
        _labelViewContainerID = -1;
    }

    private boolean replaceLayout(View target) {
        if (getParent() != null || target == null || target.getParent() == null || _labelViewContainerID != -1) {
            return false;
        }

        ViewGroup parentContainer = (ViewGroup) target.getParent();

        if (target.getParent() instanceof FrameLayout) {
            ((FrameLayout) target.getParent()).addView(this);
        } else if (target.getParent() instanceof ViewGroup) {

            int groupIndex = parentContainer.indexOfChild(target);
            _labelViewContainerID = generateViewId();

            // relativeLayout need copy rule
            if (target.getParent() instanceof RelativeLayout) {
                for (int i = 0; i < parentContainer.getChildCount(); i++) {
                    if (i == groupIndex) {
                        continue;
                    }
                    View view = parentContainer.getChildAt(i);
                    RelativeLayout.LayoutParams para = (RelativeLayout.LayoutParams) view.getLayoutParams();
                    for (int j = 0; j < para.getRules().length; j++) {
                        if (para.getRules()[j] == target.getId()) {
                            para.getRules()[j] = _labelViewContainerID;
                        }
                    }
                    view.setLayoutParams(para);
                }
            }
            parentContainer.removeView(target);

            // new dummy layout
            FrameLayout labelViewContainer = new FrameLayout(getContext());
            ViewGroup.LayoutParams targetLayoutParam = target.getLayoutParams();
            labelViewContainer.setLayoutParams(targetLayoutParam);
            target.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

            // add target and label in dummy layout
            labelViewContainer.addView(target);
            labelViewContainer.addView(this);
            labelViewContainer.setId(_labelViewContainerID);

            // add dummy layout in parent container
            parentContainer.addView(labelViewContainer, groupIndex, targetLayoutParam);
        }
        return true;
    }

    private void calcOffset(int labelWidth, int distance, Gravity gravity, int targetWidth, boolean isDP) {

        int d = dip2Px(distance);
        int tw = isDP ? dip2Px(targetWidth) : targetWidth;

        float edge = (float) ((labelWidth - 2 * d) / (2 * 1.414));
        if (gravity == Gravity.LEFT_TOP) {
            _anchorx = -edge;
            _offsetx = _anchorx;
            _angel = -45;
        } else if (gravity == Gravity.RIGHT_TOP) {
            _offsetx = tw + edge - labelWidth;
            _anchorx = tw + edge;
            _angel = 45;
        }

        _anchory = (float) (1.414 * d + edge);
        _offsety = _anchory;

        clearAnimation();
        startAnimation(_animation);
    }

    private int dip2Px(float dip) {
        return (int) (dip * getContext().getResources().getDisplayMetrics().density + 0.5f);
    }

    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

    public static int generateViewId() {
        for (; ; ) {
            final int result = sNextGeneratedId.get();
            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
            int newValue = result + 1;
            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
            if (sNextGeneratedId.compareAndSet(result, newValue)) {
                return result;
            }
        }
    }
}

相关文章推荐

android 自定义控件(FloatLabelLayout)

原帖地址:https://gist.github.com/chrisbanes/11247418

Android控件之LabelView

最近研究android控件开发,学习无捷径,逛github,看到一个LabelView的demo,感觉还是挺不错,也比较实用,所以拿来学习了一下。         附上源项目的地址:https://g...

Android自定义标签LabelView详细思路及过程

自定义LabelTextView项目需要,实现一个圆角矩形加上标签的自定义View。大概的效果是这样的难点 标签页的范围需要贴合圆角矩形的范围 标签内的字体需要和和线平行 以及各种坑 遇到问题和解决方...

Android View标签LabelView(电商、商城类APP常用)

 Android View标签LabelView(电商、商城类APP常用) LabelView是在github上一个开源的标签库。其项目主页是:https://github.com/linge...

android 自定义LabelView实现各类小标签,重要功能已标注

转载请注明出处:王亟亟的大牛之路一个自定义TextView可实现各种控件右上,左上等位置附带便签实现。项目结构: 运行效果: 只需要一个类就可以完成以上实现 LabelViewpublic cl...

同一个Label不同样式

  • 2017年02月28日 09:08
  • 23.87MB
  • 下载

iOS文字样式处理总结(字体、前背景色、斜体、加粗、对齐、行间距、段间距、动态获取字符串label宽高等)

IOS 文字样式处理总结(字体、前背景色、斜体、加粗、对齐、行间距、段间距、动态获取字符串label宽高等) 在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线...

UILabel样式自定义(同一个Label展示不同颜色,字体)

在开发中,有时会遇到某字符串字体跟其他的不一样的需求 第一个字的字号会不一样 这个时候,其实用一个UILabel就可以轻松搞定了,方法如下: - (void)smallRMBByL...

Android文本样式——上

原文地址:http://blog.csdn.net/lixin84915/article/details/8110667 在android中,有时候需要对文本进行各种特别的设置,比如...
  • penwan
  • penwan
  • 2015年06月01日 17:46
  • 229

Android——AndroidStudio主题样式、字体设置

AndroidStudio自带的主题样式只有Darcula、Intellij、Windows三种,但是可以到其他网站上去下载主题样式进行导入。首先说一下如何设置主题自带的样式。 切换自带的主题 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android——Label样式
举报原因:
原因补充:

(最多只允许输入30个字)