美文网首页Android开发Android知识半栈工程师
安卓自定义一个二级标签选择器

安卓自定义一个二级标签选择器

作者: 勤能不能补拙 | 来源:发表于2017-12-05 18:46 被阅读0次

先来看效果图吧“


gif5新文件.gif

这个东西的总体思路是记录每一个标签的在viewgroup中的位置,然后再让每个一级标签对应起来他的二级标签,除啊是状态的时候显示所有的一级标签,然后点击每个一级标签的时候,让所有的一级标签收回到中心点位置,并让对应的二级标签扩展到半径外的位置,然后让上一级按钮显示出来,这么做可能在初始化的时候时间要久一点,应为要一次性划出所有的便签,但是之后的操作很流畅,不过有个问题就是如果一级以及二级标签太多的话(十几个),界面会显得很乱,并且标签可能会重叠,不过项目中一般那种巨大的便签不会这么设计,除非有病,这个用来做一些量不是很大的二级选择还是不错的,(一般一级标签,二级标签到不要超过十个效果应该最好)


public class  RoundView  extends  RelativeLayout {

//屏幕的宽

private int  widthPixels;

//屏幕的高

private int  heightPixels;

//默认半径

private int  defultR=300;

private  Contex  tcontext;
//这个是一级标签的数据
private  ArrayList  data=new  ArrayList();
//这个是二级标签的数据,大集合中有个小集合,小集合对应的的位置就是一级标签的为止
private ArrayList<ArrayList<String>> childData = new ArrayList();

//这个是每个二级标签对应的位置(这个位置是指在整个view group中的子view的位置)
private ArrayList<ArrayList<Integer>> childDataindex = new ArrayList();

//这个是一级标签对应的位置
private ArrayList<Integer> Dataindex = new ArrayList();

//这个是当前打开的二级标签位置的集合
private ArrayList<Integer> integers;

private intmainMenuColor=0;

private intitemMenuColor=0;

public intget  WidthPixels() {

return  widthPixels;

}

public void  setWidth  Pixels(int  widthPixels) {

this.widthPixels= widthPixels;

}

public intget  MainMenuColor() {

return  mainMenuColor;

}

public void  setMainMenuColor(int  mainMenuColor) {

this.mainMenuColor= mainMenuColor;

}

public intget  ItemMenuColor() {

return  itemMenuColor;

}

public void  setItemMenuColor(int  itemMenuColor) {

this.itemMenuColor= itemMenuColor;

}

public  RoundView(Context context) {

this(context, null);

}

public  RoundView(Context context,AttributeSet attrs) {

this(context,attrs,0);

}

public  RoundView(Context context,AttributeSet attrs, int  defStyleAttr) {

super(context,attrs,defStyleAttr);

init(context);

}
 //这个方法是将一个一级便签和其对应的二级标签添加到集合中的
 public void setData(String s, ArrayList<String> child) {
        //将一组数据添加到集合
        int childsize = 0;
        for (int i = 0; i < childDataindex.size(); i++) {
            childsize = childsize + childDataindex.get(i).size();
        }
        Dataindex.add(data.size() + childsize);
        data.add(s);

        childData.add(child);
        //主按钮的长度
        int size = data.size();
        int childsize1 = 0;
        for (int i = 0; i < childDataindex.size(); i++) {
            childsize1 = childsize1 + childDataindex.get(i).size();
        }
        int allSize = size + childsize1;

        ArrayList<Integer> integers = new ArrayList<>();
        for (int i = 0; i < child.size(); i++) {
            integers.add(allSize + i);
        }
        childDataindex.add(integers);
    }
//这个是初始化方法
 private void init(final Context context) {
        this.context = context;
        DisplayMetrics dm = new DisplayMetrics();
        Activity activity = (Activity) context;
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        widthPixels = dm.widthPixels;
        heightPixels = dm.heightPixels;
        defultR = widthPixels / 5;

        for (int i = 0; i < data.size(); i++) {
            final TextView textView = new TextView(context);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(defultR, defultR);
            textView.setLayoutParams(layoutParams);
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(18);
            textView.setEnabled(false);
            textView.setVisibility(INVISIBLE);
            textView.setText(data.get(i));
            textView.setTextColor(Color.WHITE);
            //textView.setBackgroundColor(Color.RED);
            textView.setBackgroundResource(R.drawable.tv_shap);
            if (mainMenuColor!=0){
                GradientDrawable p = (GradientDrawable)textView.getBackground();
                p.setColor(mainMenuColor);
            }
            final int finalI = i;
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    downAnimal(Dataindex.get(finalI), finalI);
                }
            });
            this.addView(textView);
            final ArrayList<String> arrayList = childData.get(i);
            for (int k = 0; k < arrayList.size(); k++) {
                final TextView textView1 = new TextView(context);
                LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(defultR, defultR);
                textView1.setLayoutParams(layoutParams1);
                textView1.setGravity(Gravity.CENTER);
                textView1.setTextSize(18);
                textView1.setText(arrayList.get(k));
                textView1.setTextColor(Color.WHITE);
                //textView.setBackgroundColor(Color.RED);
                textView1.setBackgroundResource(R.drawable.tv1_shap);
                if (itemMenuColor!=0){
                    GradientDrawable p1 = (GradientDrawable)textView1.getBackground();
                    p1.setColor(itemMenuColor);
                }
                final int finalK = k;
                textView1.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Toast.makeText(context, arrayList.get(finalK), Toast.LENGTH_SHORT).show();
                    }
                });
                textView1.setVisibility(INVISIBLE);
                this.addView(textView1);
            }
        }
    }


 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
    }

    //重新布局
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final TextView child = (TextView) this.getChildAt(i);
            int width = child.getLayoutParams().width;
            int height = child.getLayoutParams().height;
            child.layout(right / 2 - width / 2, bottom / 2 - height / 2, right / 2 + width / 2, bottom / 2 + height / 2);
        }
    }

   //调用这个方法来创建这个组合标签
   public void creat() {
        init(context);
        initRetunt();
        upAninmal();
    }
    //这个方法是设置上一级按钮的
    private void initRetunt() {
        final TextView textView2 = new TextView(context);
        LinearLayout.LayoutParams layoutParams2 = new                     
        LinearLayout.LayoutParams(defultR, defultR);
        textView2.setLayoutParams(layoutParams2);
        textView2.setGravity(Gravity.CENTER);
        textView2.setTextSize(18);
        textView2.setText("上一级");
        textView2.setTextColor(Color.WHITE);
        //textView.setBackgroundColor(Color.RED);
        textView2.setBackgroundResource(R.drawable.tv_shap);
        if (mainMenuColor!=0){
            GradientDrawable p2 = (GradientDrawable)textView2.getBackground();
            p2.setColor(mainMenuColor);
        }
        textView2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                retunAnimal();
            }
        });
        textView2.setVisibility(INVISIBLE);
        this.addView(textView2);
    }
 //这个方法是二级标签展开的动画
 private void upAninmal() {
        int childCount = data.size();
        int childitem = childCount;
        //百分比
        if (childitem != 0) {
            int roud = 360 / childitem;
            for (int i = 0; i < childCount; i++) {
                double x = 0;
                double y = 0;
                final TextView childAt = (TextView) getChildAt(Dataindex.get(i));
                x = 0 + defultR*1.5 * Math.cos(roud * i * Math.PI / 180);
                y = 0 + defultR*1.5 * Math.sin(roud * i * Math.PI / 180);
                ObjectAnimator.ofFloat(childAt, "translationX", 0, (int) x).setDuration(500).start();
                ObjectAnimator.ofFloat(childAt, "translationY", 0, (int) y).setDuration(500).start();
                final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha",  1.0f).setDuration(500);
                alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float value = (Float) alpha.getAnimatedValue();
                        Log.d("value", String.valueOf(value));
                        if (value > 0.5f) {
                            childAt.setVisibility(VISIBLE);
                        }
                        if (value ==1f) {
                            childAt.setEnabled(true);
                        }
                    }
                });
                alpha.start();
            }
        }

    }
 //这个是关闭的动画及操作
private void downAnimal(Integer finalI, int index) {

        for (int i = 0; i < data.size(); i++) {
            final View childAt = getChildAt(Dataindex.get(i));
            childAt.setEnabled(false);
            ObjectAnimator.ofFloat(childAt, "translationX", 0).setDuration(500).start();
            ObjectAnimator.ofFloat(childAt, "translationY", 0).setDuration(500).start();
            final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f).setDuration(500);
            alpha.start();
            alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (Float) alpha.getAnimatedValue();
                    if (value <= 0.5f) {
                        childAt.setVisibility(INVISIBLE);
                    }
                }
            });

        }
        integers = childDataindex.get(index);
        int childitem = integers.size();
        final TextView retun = (TextView) getChildAt(getChildCount() - 1);
        for (int i = 0; i < integers.size(); i++) {
            final View childAt = getChildAt(integers.get(i));
            int roud = 360 / childitem;
            double x = 0;
            double y = 0;
            x = 0 + defultR*1.5 * Math.cos(roud * i * Math.PI / 180);
            y = 0 + defultR*1.5 * Math.sin(roud * i * Math.PI / 180);
            ObjectAnimator.ofFloat(childAt, "translationX", 0, (int) x).setDuration(500).start();
            ObjectAnimator.ofFloat(childAt, "translationY", 0, (int) y).setDuration(500).start();
            final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f, 0.5f
                    , 1f).setDuration(500);
            alpha.start();
            alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (Float) alpha.getAnimatedValue();
                    if (value >= 0.5f) {
                        childAt.setVisibility(VISIBLE);
                        retun.setVisibility(VISIBLE);
                    }
                    if (value==1f){
                        childAt.setEnabled(true);
                        retun.setEnabled(true);
                    }

                }
            });
        }
    }

 /**
     * 返回上一级的动画
     */
    private void retunAnimal() {
        final TextView retun = (TextView) getChildAt(getChildCount() - 1);
        for (int i = 0; i < integers.size(); i++) {
            final View childAt = getChildAt(integers.get(i));
            ObjectAnimator.ofFloat(childAt, "translationX", 0).setDuration(500).start();
            ObjectAnimator.ofFloat(childAt, "translationY", 0).setDuration(500).start();
            final ObjectAnimator alpha = ObjectAnimator.ofFloat(childAt, "alpha", 0f).setDuration(500);
            alpha.start();
            childAt.setEnabled(false);
            retun.setEnabled(false);
            alpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float value = (Float) alpha.getAnimatedValue();
                    if (value <= 0.5f) {
                        childAt.setVisibility(INVISIBLE);
                        retun.setVisibility(INVISIBLE);
                    }
                }
            });
        }
        upAninmal();
    }

另外用法也很简单

 roundView = (RoundView) findViewById(R.id.mv);
        //搞一些假数据
        ArrayList<String> firstPage = new ArrayList<>();
        firstPage.add("小学");
        firstPage.add("初中");
        firstPage.add("高中");
        firstPage.add("大学");
        firstPage.add("上班族");
        firstPage.add("留学");
        firstPage.add("学前");
        ArrayList<String> secondPage = new ArrayList<>();

        secondPage.add("一年级");
        secondPage.add("二年级");
        secondPage.add("三年级");
        secondPage.add("四年级");
        secondPage.add("五年级");
        secondPage.add("六年级");

        //设置每一组标签
        for (int i = 0; i < firstPage.size(); i++) {
            roundView.setData(firstPage.get(i),secondPage);
        }
        //一级标签的颜色
        roundView.setMainMenuColor(Color.BLUE);
        //二级标签的颜色
        roundView.setItemMenuColor(Color.BLUE);
        roundView.creat();

另外就是这个是自己随便写的一个demo,项目中没有使用,所以没做神们扩展,很多可以搞的属性没有搞,可以封装的地方没有封装,请见谅,只是像请大神指点这个思路怎们样,怎么优化呢
代码地址
https://github.com/wxxewx/RoundMenu

相关文章

  • 安卓自定义一个二级标签选择器

    先来看效果图吧“ 这个东西的总体思路是记录每一个标签的在viewgroup中的位置,然后再让每个一级标签对应起来他...

  • 学习自定义View的一些文章

    安卓自定义View基础:坐标系 安卓自定义View基础:角度弧度 安卓自定义View基础:颜色 Android自定...

  • 安卓自定义View教程-1

    基础篇 安卓自定义View基础 - 坐标系 安卓自定义View基础 - 角度弧度 安卓自定义View基础 - 颜色...

  • css_选择器分类

    1. 标签选择器 标签{属性:值;} 选择标签并赋予样式 2. 类选择器 自定义类名{属性:值;} 一个标签可以调...

  • css选择器

    选择器是一个选择器谁的过程。 一、基础选择器 1.标签选择器 标签(属性:值;) 2.类选择器 .自定义类名(属性...

  • 安卓自定义标签

    最近在某安卓开发QQ群看到这样一个需求 大家推荐用RL或者FL加切图的方式实现为了提高自己的自定义控件水平(其实是...

  • [转]自定义View的学习

    原文连接 如何关闭硬件加速 自定义View 基础篇 安卓自定义View基础 - 坐标系 安卓自定义View基础 -...

  • 小记

    小程序 自定义组件 在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

  • 自定义View教程目录

    参考安卓自定义View教程目录

  • 极光推送 java util

    publicclassJPushUtil { /** * 安卓iOS标签推送 *@paramtagValues 标...

网友评论

    本文标题:安卓自定义一个二级标签选择器

    本文链接:https://www.haomeiwen.com/subject/olgcixtx.html