Android Lableview给控件添加标签
2015-09-15 15:42
465 查看
我们通常需要给一张图片左侧顶部添加一个标签什么的,例如商品的热卖,左侧顶部添加一个hot标签。
下面这个自定义view LabelView就可以很好的帮助你,把这个自定义view复制到你的项目中,然后在activity中添加如下代码:
第一个参数表示你要添加到哪个view上,第二个参数你lableview的位置,第三个参数是lableview的所属方位,
另外如果是用在baseAdapter中:
移除lableview:label.remove();
自定义的lableview代码:
github原项目地址
下面这个自定义view LabelView就可以很好的帮助你,把这个自定义view复制到你的项目中,然后在activity中添加如下代码:
LabelView label = new LabelView(this); label.setText("POP"); label.setBackgroundColor(0xff03a9f4); label.setTargetView(findViewById(R.id.text), 10, LabelView.Gravity.LEFT_TOP);
第一个参数表示你要添加到哪个view上,第二个参数你lableview的位置,第三个参数是lableview的所属方位,
另外如果是用在baseAdapter中:
public View getItemView(int position, View convertView, ViewHolder holder) { ...... // you have to generate label ID manual LabelView label = holder.getView(12345); if (label == null) { label = new LabelView(this); label.setId(12345); label.setBackgroundColor(0xffE91E63); label.setTargetViewInBaseAdapter(imageView, 138, 10, LabelView.Gravity.LEFT_TOP); } label.setText(your data); return convertView; }
移除lableview:label.remove();
自定义的lableview代码:
github原项目地址
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; } } } }
相关文章推荐
- (整理篇一)在windows环境下搭载Android开发环境
- Android不发版也能在线修Bug?——AndFix 框架
- 学习android编程之路(8)—Android中Cursor类的概念和用法
- (转)Android项目重构之路:实现篇
- Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
- Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能
- (转)Android项目重构之路:界面篇
- Android DiskLruCache完全解析,硬盘缓存的最佳方案
- Android Volley完全解析(一),初识Volley的基本用法
- Android PackageManager 用法
- Android PackageManager 用法
- Dex文件的完整性校验
- Android之联系人A~Z快速索引效果
- Android之联系人A~Z快速索引效果
- 六款值得推荐的Android开源框架简介
- android环境配置
- Android代码优化(一)
- 【Android】Android清除本地数据缓存代码
- Android多媒体之音频、视频录制MediaRecorder
- android 自定义打开文件的类型