文档章节

Android 移动换位小标签(类似小红帽)

胖子白
 胖子白
发布于 2016/06/20 13:50
字数 1154
阅读 13
收藏 0
点赞 0
评论 0

 

ILabelView 代码:

package com.jm.labelviewdemo;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by FatWhite on 2015/11/25.
 */
public class ILabelView extends RelativeLayout {
    private static final int ANIMATIONEACHOFFSET = 600;
    //圆点中心点
    private int mTop;
    private int mLeft;
    //计算在父布局位置参数
    private int _xDelta;
    private int _yDelta;
    private ImageView labelIcon;
    private TextView text1;
    private TextView text2;
    private TextView text3;
    private TextView text4;
    private TextView text5;
    private TextView text6;
    private int type = 1;
    private int parentWidth = 0;
    int iconWidth = 0;
    int iconHeight = 0;
    private ArrayList<TextView> aList = new ArrayList<TextView>();

    public ILabelView(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.label_view, this);
        labelIcon = (ImageView) findViewById(R.id.label_icon);
        text1 = (TextView) findViewById(R.id.text1);
        text2 = (TextView) findViewById(R.id.text2);
        text3 = (TextView) findViewById(R.id.text3);
        text4 = (TextView) findViewById(R.id.text4);
        text5 = (TextView) findViewById(R.id.text5);
        text6 = (TextView) findViewById(R.id.text6);
        aList.add(text1);
        aList.add(text2);
        aList.add(text3);
        aList.add(text4);
        aList.add(text5);
        aList.add(text6);
        updateVisibility();
        int w = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        int h = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        labelIcon.measure(w, h);
        iconWidth = labelIcon.getMeasuredWidth();
        iconHeight = labelIcon.getMeasuredHeight();
        labelIcon.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                type = type == 6 ? 1 : ++type;
                updateVisibility();
                updateLocation(mLeft, mTop);
            }
        });
    }

    public ILabelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.label_view, this);
        labelIcon = (ImageView) findViewById(R.id.label_icon);
        text1 = (TextView) findViewById(R.id.text1);
        text2 = (TextView) findViewById(R.id.text2);
    }
    //初次调用画布局,啦啦啦啦
    public void draw(ViewGroup parent, int mLeft, int mTop) {
        this.parentWidth = parent.getWidth();
        this.mLeft = mLeft;
        this.mTop = mTop;
        updateLocation(mLeft, mTop);
        parent.addView(this);

    }

    //点击的时候更换label背景
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private void updateLocation(int mLeft, int mTop) {
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        int w = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        int h = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        LayoutParams iconparams = (LayoutParams) labelIcon.getLayoutParams();
        switch (type) {
            case 1:
                LayoutParams p1 = (LayoutParams) text1.getLayoutParams();
                p1.setMargins(0, 0, iconWidth / 2, iconHeight / 2);
                text1.setLayoutParams(p1);
                text1.measure(w, h);
                params.width = text1.getMeasuredWidth() + iconWidth / 2;
                params.height = text1.getMeasuredHeight() + iconHeight / 2;
                iconparams.removeRule(RelativeLayout.CENTER_VERTICAL);
                iconparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                iconparams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                params.setMargins(mLeft - text1.getMeasuredWidth(), mTop - text1.getMeasuredHeight(), 0, 0);
                break;
            case 2:
                LayoutParams p2 = (LayoutParams) text2.getLayoutParams();
                p2.setMargins(iconWidth / 2, 0, 0, iconHeight / 2);
                text2.setLayoutParams(p2);
                text2.measure(w, h);
                params.width = text2.getMeasuredWidth() + iconWidth / 2;
                params.height = text2.getMeasuredHeight() + iconHeight / 2;
                iconparams.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                iconparams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                params.setMargins(mLeft - iconWidth / 2, mTop - text2.getMeasuredHeight(), 0, 0);
                break;
            case 3:
                LayoutParams p3 = (LayoutParams) text3.getLayoutParams();
                p3.setMargins(iconWidth / 2, 0, 0, 0);
                text3.setLayoutParams(p3);
                text3.measure(w, h);
                params.width = text3.getMeasuredWidth() + iconWidth / 2;
                params.height = text3.getMeasuredHeight();
                iconparams.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                iconparams.addRule(RelativeLayout.CENTER_VERTICAL);
                params.setMargins(mLeft - iconWidth / 2, mTop - text3.getMeasuredHeight() / 2, 0, 0);
                break;
            case 4:
                LayoutParams p4 = (LayoutParams) text4.getLayoutParams();
                p4.setMargins(iconWidth / 2, iconHeight / 2, 0, 0);
                text4.setLayoutParams(p4);
                text4.measure(w, h);
                params.width = text4.getMeasuredWidth() + iconWidth / 2;
                params.height = text4.getMeasuredHeight() + iconHeight / 2;
                iconparams.removeRule(RelativeLayout.CENTER_VERTICAL);
                iconparams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                params.setMargins(mLeft - iconWidth / 2, mTop - iconHeight / 2, 0, 0);
                break;
            case 5:
                LayoutParams p5 = (LayoutParams) text5.getLayoutParams();
                p5.setMargins(0, iconHeight / 2, iconWidth / 2, 0);
                text5.setLayoutParams(p5);
                text5.measure(w, h);
                params.width = text5.getMeasuredWidth() + iconWidth / 2;
                params.height = text5.getMeasuredHeight() + iconHeight / 2;
                iconparams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
                iconparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                params.setMargins(mLeft - text5.getMeasuredWidth(), mTop - iconHeight / 2, 0, 0);
                break;
            case 6:
                LayoutParams p6 = (LayoutParams) text6.getLayoutParams();
                p6.setMargins(0, 0, iconWidth / 2, 0);
                text6.setLayoutParams(p6);
                text6.measure(w, h);
                params.width = text6.getMeasuredWidth() + iconWidth / 2;
                params.height = text6.getMeasuredHeight();
                iconparams.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
                iconparams.addRule(RelativeLayout.CENTER_VERTICAL);
                params.setMargins(mLeft - text6.getMeasuredWidth(), mTop - text6.getMeasuredHeight() / 2, 0, 0);
                break;
        }
        setLayoutParams(params);
        wave();
    }

    //小圆点动画,可以不加哦
    public void wave() {
        AnimationSet as = new AnimationSet(true);
        ScaleAnimation sa = new ScaleAnimation(1f, 1.5f, 1f, 1.5f, ScaleAnimation.RELATIVE_TO_SELF,
                0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
        sa.setDuration(ANIMATIONEACHOFFSET * 3);
        sa.setRepeatCount(10);// 设置循环
        AlphaAnimation aniAlp = new AlphaAnimation(1, 0.1f);
        aniAlp.setRepeatCount(10);// 设置循环
        as.setDuration(ANIMATIONEACHOFFSET * 3);
        as.addAnimation(sa);
        as.addAnimation(aniAlp);
        labelIcon.startAnimation(as);
    }

    //更新Visibility
    private void updateVisibility() {
        for (int i = 0; i < aList.size(); i++) {
            if (i + 1 == type) {
                aList.get(i).setVisibility(View.VISIBLE);
            } else {
                aList.get(i).setVisibility(View.GONE);
            }
        }
    }

    //移动的时候更新小小圆点中心哦
    public void updateMarginValue(int left, int top) {
        int w = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        int h = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        switch (type) {
            case 1:
                text1.measure(w, h);
                mLeft=left+text1.getMeasuredWidth();
                mTop=top+text1.getMeasuredHeight();
                break;
            case 2:
                text2.measure(w, h);
                mLeft=left+iconWidth / 2;
                mTop=top+text2.getMeasuredHeight();
                break;
            case 3:
                text3.measure(w, h);
                mLeft=left+iconWidth / 2;
                mTop=top+text3.getMeasuredHeight() / 2;
                break;
            case 4:
                text4.measure(w, h);
                mLeft=left+iconWidth / 2;
                mTop=top+iconHeight / 2;
                break;
            case 5:
                text5.measure(w, h);
                mLeft=left+text5.getMeasuredWidth();
                mTop=top+iconHeight / 2;
                break;
            case 6:
                text6.measure(w, h);
                mLeft=left+text6.getMeasuredWidth();
                mTop=top+text6.getMeasuredHeight()/2;
                break;

        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                LayoutParams lParams = (LayoutParams) this
                        .getLayoutParams();
                _xDelta = X - lParams.leftMargin;
                _yDelta = Y - lParams.topMargin;
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                LayoutParams layoutParams = (LayoutParams) this
                        .getLayoutParams();
                layoutParams.leftMargin = X - _xDelta;
                layoutParams.topMargin = Y - _yDelta;
                layoutParams.rightMargin = -250;
                layoutParams.bottomMargin = -250;
                setLayoutParams(layoutParams);
                updateMarginValue(X - _xDelta,Y - _yDelta);
                break;
        }
//        _root.invalidate();
        return true;
    }
}

 

对应xml代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/tag_1"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/tag_2"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/text3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@drawable/tag_3"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/text4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/tag_4"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/text5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/tag_5"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/text6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@drawable/tag_6"
        android:text="I'm label"
        android:textColor="#ffffff" />

    <ImageView
        android:id="@+id/label_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/dot" />

</RelativeLayout>

应用:

private void initView(){
    parentRL= (RelativeLayout) findViewById(R.id.parentRl);
    RelativeLayout.LayoutParams params= (RelativeLayout.LayoutParams) parentRL.getLayoutParams();
    params.width= (int) PhoneSize.getInstance().getWidth4pix();
    params.height=(int) PhoneSize.getInstance().getWidth4pix();
    parentRL.setLayoutParams(params);
    ILabelView labelView=new ILabelView(ParentActivity.this);
    labelView.draw(parentRL,500,500);
}

 

菜鸟一枚,有很多 不足之处请不吝指导。

© 著作权归作者所有

共有 人打赏支持
胖子白
粉丝 0
博文 14
码字总数 1976
作品 0
东城
程序员
安卓PDA的功能和特点及应用行业

  安卓PDA又称为掌上电脑,可以帮助我们完成在移动中工作,学习,娱乐等。按使用来分类,分为工业级PDA和消费品PDA。工业级PDA主要应用在工业领域,常见的有条码扫描器、RFID读写器、POS机...

sznewbest ⋅ 05/28 ⋅ 0

AndroidManifest.xml详解

我们在进行APP开发的时候都会遇到一个文件:AndroidManifest.xml。从刚开始进行Android开发,到现在已经过去了几个月,还是对这个文件一知半解,只知道它是配置用的。但是这文件里的东西具体...

闪电的蓝熊猫 ⋅ 05/14 ⋅ 0

谷歌I/O大会8大看点:有Android系统全面更新

谷歌I/O大会8大看点:有Android系统全面更新 2018-05-08 10:27编辑: 枣泥布丁分类:业界动态来源:cnBate Android谷歌I/O大会 招聘信息: C++工程师 Cocos2d-x游戏客户端开发 iOS开发工程师...

枣泥布丁 ⋅ 05/08 ⋅ 0

droidcon上海2018安卓技术大会将于6月亮相魔都

摘要:droidcon自2016年登陆帝都北京后,经历两届大会历练,本届将于2018年6月28-29日首次亮相魔都上海。作为德国Mobile Seasons GmbH、北京长风信息技术产业联盟与MWC世界移动大会主办方全球...

driodcon ⋅ 05/10 ⋅ 0

浅入浅出 Android 安全:第二章 Android Linux 内核层安全

第二章 Android Linux 内核层安全 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 作为最广为人知的开源项目之一,Linux 已经被证明是一个安全,可信和稳定的软...

apachecn_飞龙 ⋅ 2016/11/30 ⋅ 0

浅入浅出 Android 安全:第一章 Android

第一章 Android 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 Android 安全架构的理解不仅帮助我了解 Android 的工作原理,而且为我开启了如何构建移动操作系...

apachecn_飞龙 ⋅ 2016/11/27 ⋅ 0

[图]Chrome启用Material Design设计语言初探

自今年3月份Android P发布以来,关于Google未来设计方向的讨论就从未终止过。从最新登陆Canary通道的Windows端Chrome版本中,可以知道此前被热议的“Material Design 2”可能叫做“Material ...

稿源: ⋅ 04/25 ⋅ 0

Android开发权威指南(第2版)新书发布

《Android开发权威指南(第二版)》是畅销书《Android开发权威指南》的升级版,内容更新超过80%,是一本全面介绍Android应用开发的专著,拥有45章精彩内容供读者学习。  《Android开发权威指...

androidguy ⋅ 2013/09/05 ⋅ 0

带来手势操作的 Android P beta 发布,Pixel 尝鲜

Google 2018 I/O 大会正在进行,Android P Beta 公测版目前已经发布。 下载地址 >>> https://developer.android.com/preview/download Android P Beta 计划针对 Pixel 手机开放 —— 今天开始......

局长 ⋅ 05/09 ⋅ 4

Chrome 67 for Android发布

谷歌周四宣布,它发布了用于其Android手机操作系统的Chrome 67网络浏览器,并将通过Google Play Store推出给全球用户。 在将Chrome 67发布到Linux,Mac和Windows用户之后,Google现在开始向全...

linux-tao ⋅ 前天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

服务网关过滤器

过滤器作用 我们的微服务应用提供的接口就可以通过统一的API网关入口被客户端访问到了。但是,每个客户端用户请求微服务应用提供的接口时,它们的访问权限往往都需要有一定的限制,系统并不会...

明理萝 ⋅ 7分钟前 ⋅ 1

【2018.06.21学习笔记】【linux高级知识 14.1-14.3】

14.1 NFS介绍 14.2 NFS服务端安装配置 14.3 NFS配置选项

lgsxp ⋅ 16分钟前 ⋅ 0

Day18 vim编辑模式、命令模式与练习

编辑模式 命令模式 :nohl 不高亮显示 :x与:wq类似,如果在更改文件之后操作,两者效果一样;如果打开文件,没有任何操作; :wq会更改mtime,但是:x不会。 练习题 扩展 vim的特殊用法 ht...

杉下 ⋅ 19分钟前 ⋅ 0

Enum、EnumMap、EnumSet

1、Enum 不带参数 public enum Car { AUDI { @Override public int getPrice() { return 25000; } }, MERCEDES { ......

职业搬砖20年 ⋅ 20分钟前 ⋅ 0

Java中的锁使用与实现

1.Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。 在Lock出现之前,java程序是靠synchronized关键字实现锁功能的,而Java SE5之后,...

ZH-JSON ⋅ 21分钟前 ⋅ 0

线程组和 ThreadLocal

前言 在上面文章中,我们从源码的角度上解析了一下线程池,并且从其 execute 方法开始把线程池中的相关执行流程过了一遍。那么接下来,我们来看一个新的关于线程的知识点:线程组。 线程组 ...

猴亮屏 ⋅ 23分钟前 ⋅ 0

相对路径和绝对路径

基本概念   文件路径就是文件在电脑中的位置,表示文件路径的方式有两种,相对路径和绝对路径。在网页设计中通过路径可以表示链接,插入图像、Flash、CSS文件的位置。   物理路径:物理路...

临江仙卜算子 ⋅ 27分钟前 ⋅ 0

消息队列属性及常见消息队列介绍

什么是消息队列? 消息队列是在消息的传输过程中保存消息的容器,用于接收消息并以文件的方式存储,一个队列的消息可以同时被多个消息消费者消费。分布式消息服务DMS则是分布式的队列系统,消...

中间件小哥 ⋅ 29分钟前 ⋅ 0

java程序员使用web3j进行以太坊开发详解

如何使用web3j为Java应用或Android App增加以太坊区块链支持,教程内容即涉及以太坊中的核心概念,例如账户管理包括账户的创建、钱包创建、交易转账,交易与状态、智能合约开发与交互、过滤器...

笔阁 ⋅ 29分钟前 ⋅ 0

vim编辑模式、vim命令模式

vim编辑模式 使用vim filename 进入的界面是一般模式,在这个模式下虽然我们能够查看,复制,剪切,粘贴,但是不能编辑新的内容,如何能直接写入东西呢?这就需要进入编辑模式了,从一般模式...

李超小牛子 ⋅ 32分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部